SQL分组查询问题(获取某商品最近两次在各地区的销售)

时间:2022-03-12 06:19:00
例如这样一个 销售表
商品 地区 日期 销量
A1 广州 2015/5/1 11
A1 上海 2015/5/1 22
A1 成都 2015/7/1 33
A1 广州 2015/8/1 44
A2 广州 2015/6/1 55
A3 上海 2015/7/1 66
A3 广州 2015/7/1 77
A3 广州 2015/8/1 99
A3 上海 2015/8/1 100
A3 广州 2015/10/1 100
A3 上海 2015/10/1 101
A3 成都 2015/10/1 102
A3 北京 2015/10/1 103

我想在一次查询当中,获取每个商品的最近两次在各地区的销量情况。结果如下,请问怎么实现????????
货号 日期 销量 地区
A1 2015/7/1 33 成都
A1 2015/8/1 44 广州
A2 2015/6/1 55 广州
A3 2015/8/1 99 广州
A3 2015/8/1 100 上海
A3 2015/10/1 100 广州
A3 2015/10/1 101 上海
A3 2015/10/1 102 成都
A3 2015/10/1 103 北京

PS:
SELECT * FROM 销售表 AS 临时表
WHERE (SELECT COUNT(*) FROM 销售表 WHERE(条码=临时表.条码 AND 档期日期>临时表.档期日期))<2;
结果:
货号 日期 销量 地区
A1 2015/7/1 33 成都
A1 2015/8/1 44 广州
A2 2015/6/1 55 广州
A3 2015/10/1 100 广州
A3 2015/10/1 101 上海
A3 2015/10/1 102 成都
A3 2015/10/1 103 北京

试了以上的代码,但不是我的结果,少了横线那两条记录。

9 个解决方案

#1


用排名函数 row number ()over(partition by  货号,地区 order by 日期) 取得排序号,
再查询排序号≤2的数据
大概的思路就这样吧
希望对你有帮助

#2


use Tempdb
go
--> --> 
 
declare @销售表 table([商品] nvarchar(22),[地区] nvarchar(22),[日期] Date,[销量] int)
Insert @销售表
select N'A1',N'广州','2015/5/1',11 union all
select N'A1',N'上海','2015/5/1',22 union all
select N'A1',N'成都','2015/7/1',33 union all
select N'A1',N'广州','2015/8/1',44 union all
select N'A2',N'广州','2015/6/1',55 union all
select N'A3',N'上海','2015/7/1',66 union all
select N'A3',N'广州','2015/7/1',77 union all
select N'A3',N'广州','2015/8/1',99 union all
select N'A3',N'上海','2015/8/1',100 union all
select N'A3',N'广州','2015/10/1',100 union all
select N'A3',N'上海','2015/10/1',101 union all
select N'A3',N'成都','2015/10/1',102 union all
select N'A3',N'北京','2015/10/1',103
 
SELECT * FROM (Select *,DENSE_RANK()OVER(PARTITION BY [商品] ORDER BY [日期] DESC) AS RN from @销售表) AS a WHERE RN<=2 ORDER BY 1,3
/*
商品 地区 日期 销量 RN
A1 成都 2015-07-01 33 2
A1 广州 2015-08-01 44 1
A2 广州 2015-06-01 55 1
A3 广州 2015-08-01 99 2
A3 上海 2015-08-01 100 2
A3 广州 2015-10-01 100 1
A3 上海 2015-10-01 101 1
A3 成都 2015-10-01 102 1
A3 北京 2015-10-01 103 1
*/

#3


这样改也可以
declare @销售表 table([商品] nvarchar(22),[地区] nvarchar(22),[日期] Date,[销量] int)
Insert @销售表
select N'A1',N'广州','2015/5/1',11 union all
select N'A1',N'上海','2015/5/1',22 union all
select N'A1',N'成都','2015/7/1',33 union all
select N'A1',N'广州','2015/8/1',44 union all
select N'A2',N'广州','2015/6/1',55 union all
select N'A3',N'上海','2015/7/1',66 union all
select N'A3',N'广州','2015/7/1',77 union all
select N'A3',N'广州','2015/8/1',99 union all
select N'A3',N'上海','2015/8/1',100 union all
select N'A3',N'广州','2015/10/1',100 union all
select N'A3',N'上海','2015/10/1',101 union all
select N'A3',N'成都','2015/10/1',102 union all
select N'A3',N'北京','2015/10/1',103

SELECT *
FROM @销售表 a
WHERE EXISTS(SELECT 1 FROM @销售表 WHERE a.商品 = 商品 AND 日期 > a.日期 HAVING COUNT(DISTINCT 日期) < 2)

#4


首先,谢谢大神们的回复!
我忘了和说我只是在ACCESS使用的,所以我在ACCESS里试了,提示了错误
二楼大神的
SQL分组查询问题(获取某商品最近两次在各地区的销售)

三楼大神的报出我传不上来,不好意思。
估计是都是ACCESS的兼容问题,麻烦大神们再帮忙治治。

#5


SQL分组查询问题(获取某商品最近两次在各地区的销售)
@三楼大神

#6


哦,原来是access ,试下这个

SELECT a.商品,a.地区,a.日期,a.销量
FROM 销售表 a
where a.日期 in (select distinct top 2 日期 from 销售表 where 商品 = a.商品 order by 日期 desc)


看下有没有其他高手提供个效率高点的方法来学习一下

#7


引用 1 楼 kingtiy 的回复:
用排名函数 row number ()over(partition by  货号,地区 order by 日期) 取得排序号,
再查询排序号≤2的数据
大概的思路就这样吧
希望对你有帮助

测试后,row number() 是各个商品在各地区最近两次的销量,dense_rank()可以查找所需记录

#8


“获取每个商品的最近两次在各地区的销量情况"
我按你的理解,做出的结果应该是 11条数据,你的为什么少了A1 的2条啊。。
A1 广州 2015-08-01 00:00:00.000 44
A1 广州 2015-05-01 00:00:00.000 11
A1 成都 2015-07-01 00:00:00.000 33
A1 上海 2015-05-01 00:00:00.000 22
A2 广州 2015-06-01 00:00:00.000 55
A3 广州 2015-10-01 00:00:00.000 100
A3 广州 2015-08-01 00:00:00.000 99
A3 上海 2015-10-01 00:00:00.000 101
A3 上海 2015-08-01 00:00:00.000 100
A3 成都 2015-10-01 00:00:00.000 102
A3 北京 2015-10-01 00:00:00.000 103

#9


select 商品,地区,日期,销量 from (
select row_number()over(partition by 地区,商品 order by 日期 desc) as 行数, * from  @销售表) as a  where 行数<=2 order by 商品

#1


用排名函数 row number ()over(partition by  货号,地区 order by 日期) 取得排序号,
再查询排序号≤2的数据
大概的思路就这样吧
希望对你有帮助

#2


use Tempdb
go
--> --> 
 
declare @销售表 table([商品] nvarchar(22),[地区] nvarchar(22),[日期] Date,[销量] int)
Insert @销售表
select N'A1',N'广州','2015/5/1',11 union all
select N'A1',N'上海','2015/5/1',22 union all
select N'A1',N'成都','2015/7/1',33 union all
select N'A1',N'广州','2015/8/1',44 union all
select N'A2',N'广州','2015/6/1',55 union all
select N'A3',N'上海','2015/7/1',66 union all
select N'A3',N'广州','2015/7/1',77 union all
select N'A3',N'广州','2015/8/1',99 union all
select N'A3',N'上海','2015/8/1',100 union all
select N'A3',N'广州','2015/10/1',100 union all
select N'A3',N'上海','2015/10/1',101 union all
select N'A3',N'成都','2015/10/1',102 union all
select N'A3',N'北京','2015/10/1',103
 
SELECT * FROM (Select *,DENSE_RANK()OVER(PARTITION BY [商品] ORDER BY [日期] DESC) AS RN from @销售表) AS a WHERE RN<=2 ORDER BY 1,3
/*
商品 地区 日期 销量 RN
A1 成都 2015-07-01 33 2
A1 广州 2015-08-01 44 1
A2 广州 2015-06-01 55 1
A3 广州 2015-08-01 99 2
A3 上海 2015-08-01 100 2
A3 广州 2015-10-01 100 1
A3 上海 2015-10-01 101 1
A3 成都 2015-10-01 102 1
A3 北京 2015-10-01 103 1
*/

#3


这样改也可以
declare @销售表 table([商品] nvarchar(22),[地区] nvarchar(22),[日期] Date,[销量] int)
Insert @销售表
select N'A1',N'广州','2015/5/1',11 union all
select N'A1',N'上海','2015/5/1',22 union all
select N'A1',N'成都','2015/7/1',33 union all
select N'A1',N'广州','2015/8/1',44 union all
select N'A2',N'广州','2015/6/1',55 union all
select N'A3',N'上海','2015/7/1',66 union all
select N'A3',N'广州','2015/7/1',77 union all
select N'A3',N'广州','2015/8/1',99 union all
select N'A3',N'上海','2015/8/1',100 union all
select N'A3',N'广州','2015/10/1',100 union all
select N'A3',N'上海','2015/10/1',101 union all
select N'A3',N'成都','2015/10/1',102 union all
select N'A3',N'北京','2015/10/1',103

SELECT *
FROM @销售表 a
WHERE EXISTS(SELECT 1 FROM @销售表 WHERE a.商品 = 商品 AND 日期 > a.日期 HAVING COUNT(DISTINCT 日期) < 2)

#4


首先,谢谢大神们的回复!
我忘了和说我只是在ACCESS使用的,所以我在ACCESS里试了,提示了错误
二楼大神的
SQL分组查询问题(获取某商品最近两次在各地区的销售)

三楼大神的报出我传不上来,不好意思。
估计是都是ACCESS的兼容问题,麻烦大神们再帮忙治治。

#5


SQL分组查询问题(获取某商品最近两次在各地区的销售)
@三楼大神

#6


哦,原来是access ,试下这个

SELECT a.商品,a.地区,a.日期,a.销量
FROM 销售表 a
where a.日期 in (select distinct top 2 日期 from 销售表 where 商品 = a.商品 order by 日期 desc)


看下有没有其他高手提供个效率高点的方法来学习一下

#7


引用 1 楼 kingtiy 的回复:
用排名函数 row number ()over(partition by  货号,地区 order by 日期) 取得排序号,
再查询排序号≤2的数据
大概的思路就这样吧
希望对你有帮助

测试后,row number() 是各个商品在各地区最近两次的销量,dense_rank()可以查找所需记录

#8


“获取每个商品的最近两次在各地区的销量情况"
我按你的理解,做出的结果应该是 11条数据,你的为什么少了A1 的2条啊。。
A1 广州 2015-08-01 00:00:00.000 44
A1 广州 2015-05-01 00:00:00.000 11
A1 成都 2015-07-01 00:00:00.000 33
A1 上海 2015-05-01 00:00:00.000 22
A2 广州 2015-06-01 00:00:00.000 55
A3 广州 2015-10-01 00:00:00.000 100
A3 广州 2015-08-01 00:00:00.000 99
A3 上海 2015-10-01 00:00:00.000 101
A3 上海 2015-08-01 00:00:00.000 100
A3 成都 2015-10-01 00:00:00.000 102
A3 北京 2015-10-01 00:00:00.000 103

#9


select 商品,地区,日期,销量 from (
select row_number()over(partition by 地区,商品 order by 日期 desc) as 行数, * from  @销售表) as a  where 行数<=2 order by 商品