一个SQL查询环比问题,请帮忙看看
--客户表:
create table client_tb (客户ID int,客户名称 varchar(20))
insert into client_tb select 1, '客户A'
union all select 2, '客户B'
union all select 3, '客户C'
union all select 4, '客户D'
union all select 5, '客户E'
union all select 6, '客户F'
--销售表:
create table sell_tb (单号 int,客户ID int,金额 float,日期 datetime)
insert into sell_tb select 1,'1','100','2006-6-1'
union all select 1,'1','100','2006-6-1'
union all select 2,'2','100','2006-6-1'
union all select 3,'4','100','2006-6-1'
union all select 4,'3','100','2006-6-1'
union all select 5,'3','100','2006-6-1'
union all select 6,'1','100','2006-6-2'
union all select 7,'2','100','2006-6-2'
union all select 8,'4','100','2006-6-2'
union all select 9,'5','100','2006-6-2'
union all select 10,'6','100','2006-6-2'
union all select 11,'5','100','2006-6-2'
union all select 12,'3','100','2006-6-2'
union all select 13,'4','100','2006-6-2'
union all select 14,'5','100','2006-6-3'
union all select 15,'2','100','2006-6-3'
union all select 16,'1','100','2006-6-3'
union all select 17,'1','100','2006-6-4'
union all select 18,'3','100','2006-6-4'
union all select 19,'6','100','2006-6-4'
union all select 20,'5','100','2006-6-4'
要对两天的销售金额进行比较,或者前3天与后3天的金额比较
比较要求查询出的数据按客户表进行排列,当天没有销售的客户金额用0表示
比如要查6月1日和6月2日的销售金额比较
2006-06-01金额 2006-06-02金额
客户A 100 100
客户B 100 100
客户C 200 100
客户D 100 200
客户E 0 200
客户F 0 100
我是想分别查出6月1日所有的客户的销售金额为一列,再查出6月2日的,然后使用程序将两列拼成上面那样。
问题点数:20、回复次数:14Top
1 楼paoluo(一天到晚游泳的鱼)回复于 2006-07-01 14:16:13 得分 0
Select
A.客户名称,
SUM(Case When 日期='2006-06-01' Then 金额 Else 0 End) As [2006-06-01金额],
SUM(Case When 日期='2006-06-02' Then 金额 Else 0 End) As [2006-06-02金额]
From client_tb A
Left Join sell_tb B
On A.客户ID=B.客户ID
Group By A.客户名称Top
2 楼paoluo(一天到晚游泳的鱼)回复于 2006-07-01 14:18:07 得分 10
Select
A.客户名称,
SUM(Case When 日期='2006-06-01' Then 金额 Else 0 End) As [2006-06-01金额],
SUM(Case When 日期='2006-06-02' Then 金额 Else 0 End) As [2006-06-02金额]
From client_tb A
Left Join sell_tb B
On A.客户ID=B.客户ID
Group By A.客户名称
GO
--Result
/*
客户名称 2006-06-01金额 2006-06-02金额
客户A 200.0 100.0
客户B 100.0 100.0
客户C 200.0 100.0
客户D 100.0 200.0
客户E 0.0 200.0
客户F 0.0 100.0
*/Top
3 楼LouisXIV(夜游神)回复于 2006-07-01 14:24:51 得分 5
--客户表:
create table client_tb (客户ID int,客户名称 varchar(20))
insert into client_tb select 1, '客户A'
union all select 2, '客户B'
union all select 3, '客户C'
union all select 4, '客户D'
union all select 5, '客户E'
union all select 6, '客户F'
--销售表:
create table sell_tb (单号 int,客户ID int,金额 float,日期 datetime)
insert into sell_tb select 1,'1','100','2006-6-1'
union all select 1,'1','100','2006-6-1'
union all select 2,'2','100','2006-6-1'
union all select 3,'4','100','2006-6-1'
union all select 4,'3','100','2006-6-1'
union all select 5,'3','100','2006-6-1'
union all select 6,'1','100','2006-6-2'
union all select 7,'2','100','2006-6-2'
union all select 8,'4','100','2006-6-2'
union all select 9,'5','100','2006-6-2'
union all select 10,'6','100','2006-6-2'
union all select 11,'5','100','2006-6-2'
union all select 12,'3','100','2006-6-2'
union all select 13,'4','100','2006-6-2'
union all select 14,'5','100','2006-6-3'
union all select 15,'2','100','2006-6-3'
union all select 16,'1','100','2006-6-3'
union all select 17,'1','100','2006-6-4'
union all select 18,'3','100','2006-6-4'
union all select 19,'6','100','2006-6-4'
union all select 20,'5','100','2006-6-4'
declare @sql varchar(8000)
set @sql=''
select @sql=@sql+',isnull(sum(case when 日期='''+convert(varchar(10),日期,120) +''' then 金额 else 0 end),0) as ['+convert(varchar(10),日期,120)+'金额]' from sell_tb group by 日期
select @sql='select 客户名称'+@sql+' from client_tb a left join sell_tb b on a.客户ID=b.客户ID group by 客户名称,a.客户ID'
exec (@sql)
/*
如果想选取日期范围
将
select @sql=@sql+',isnull(sum(case when 日期='''+convert(varchar(10),日期,120) +''' then 金额 else 0 end),0) as ['+convert(varchar(10),日期,120)+'金额]' from sell_tb group by 日期
改为
select @sql=@sql+',isnull(sum(case when 日期='''+convert(varchar(10),日期,120) +''' then 金额 else 0 end),0) as ['+convert(varchar(10),日期,120)+'金额]' from sell_tb
where 日期 between startdate and enddate
group by 日期
即可
*/Top
4 楼maip(net)回复于 2006-07-01 14:55:49 得分 0
paoluo的方法可行
LouisXIV的方法不是很合要求,不能group by 日期,日期应该是个可选项
感谢两位的帮助
Top
5 楼maip(net)回复于 2006-07-01 15:03:57 得分 0
paoluo能否为小弟结实一下这段语句的原理-_-小弟菜鸟
Select
A.客户名称,
SUM(Case When 日期='2006-06-01' Then 金额 Else 0 End) As [2006-06-01金额],
--这里似懂非懂,应该是当2006-6-1读到sell_tb里没有记录就返回0对吗?
SUM(Case When 日期='2006-06-02' Then 金额 Else 0 End) As [2006-06-02金额]
From client_tb A
Left Join sell_tb B --这里left jion也不会用
On A.客户ID=B.客户ID --这个ON是跟where有什么不同?
Group By A.客户名称
Top
6 楼fcuandy(了此残生.)回复于 2006-07-01 15:06:57 得分 5
魚的寫法是固定的寫法,是针对你取两天写的语句,如果你僅要取某幾天,可以這樣.
如果你要加上6-3日的,那麼語句里也要加上
SUM(Case When 日期='2006-06-01' Then 金额 Else 0 End) As [2006-06-01金额],
SUM(Case When 日期='2006-06-02' Then 金额 Else 0 End) As [2006-06-02金额],
SUM(Case When 日期='2006-06-03' Then 金额 Else 0 End) As [2006-06-03金额]
同样,如果你要查看 6-1到 6-30的,你就得写30段这样的话...
夜游神的寫法是通用的,你可以设置两个变量为起始时间和结速时间,套到夜游神的写法里,可以查任意时间段的数据,而不用再修改SQL语句.
我本来也写了一段,大意跟夜游神的一样,调试时,因为我用了繁体输法,有的字虽然看起来是简体但实际上内码不一样,提示我字段名错误之类的东西,等改完,发现他们把固定的和通用的都写了..Top
7 楼paoluo(一天到晚游泳的鱼)回复于 2006-07-01 15:09:22 得分 0
Case When 日期='2006-06-01' Then 金额 Else 0 End
當日期為'2006-06-01' 時,就得到那條紀錄的金额,否則就得到0
Left Join 左聯接
On,是和Left Join結合使用的。
你可以在聯繫幫助上看看CASE以及Left Join的用法,自己寫些語句試下。Top
8 楼maip(net)回复于 2006-07-01 15:09:40 得分 0
另外,如果我在sell_tb中还有条件要附加的话是不是这样加:
On A.客户ID=B.客户ID where B.storeid='1'
Top
9 楼paoluo(一天到晚游泳的鱼)回复于 2006-07-01 15:10:29 得分 0
對Top
10 楼fcuandy(了此残生.)回复于 2006-07-01 15:13:08 得分 0
ON是连接条件,WHERE是过滤条件.
比如
tba
aid
1
2
3
tbb
bid
1
3
select aid,bid from tba left join tbb on aid=bid
此时结果
aid bid
1 1
2 null
3 3
select aid,bid from tba left join tbb on 1=1 where aid=bid
这时where 过滤掉了aid<>bid的记录,结果是
aid bid
1 1
3 3
功能相当于
select aid,bid from tba inner join tbb on aid=bid (inner join 只取交集,即aid有的,bid也要有才选出来)
Top
11 楼maip(net)回复于 2006-07-01 15:29:27 得分 0
LouisXIV(夜游神)的第二个没办法执行
declare @sql varchar(8000)
set @sql=''
select @sql=@sql+',isnull(sum(case when 日期='''+convert(varchar(10),日期,120) +''' then 金额 else 0 end),0) as ['+convert(varchar(10),日期,120)+'金额]' from sell_tb group by 日期
select @sql=@sql+',isnull(sum(case when 日期='''+convert(varchar(10),日期,120) +''' then 金额 else 0 end),0) as ['+convert(varchar(10),日期,120)+'金额]' from sell_tb
where 日期 between '2006-06-01' and '2006-06-02'
group by 日期
print(@sql)
exec(@sql)
提示:
,isnull(sum(case when 日期='2006-06-01' then 金额 else 0 end),0) as [2006-06-01金额],isnull(sum(case when 日期='2006-06-02' then 金额 else 0 end),0) as [2006-06-02金额],isnull(sum(case when 日期='2006-06-03' then 金额 else 0 end),0) as [2006-06-03金额],isnull(sum(case when 日期='2006-06-04' then 金额 else 0 end),0) as [2006-06-04金额],isnull(sum(case when 日期='2006-06-01' then 金额 else 0 end),0) as [2006-06-01金额],isnull(sum(case when 日期='2006-06-02' then 金额 else 0 end),0) as [2006-06-02金额]
Server: Msg 170, Level 15, State 1, Line 1
Line 1: Incorrect syntax near ','.
但按我的需求应该是group by client_tb.客户名称才对,时间段是动态可选字段,而不应该一次在列将所有的日期列为列,应该是我传递进去的日期才列出来
Top
12 楼maip(net)回复于 2006-07-01 15:33:25 得分 0
用paoluo方法也可以实现时间段的需求
SUM(Case When 日期 between '2006-06-01' and '2006-06-02' Then 金额 Else 0 End) As [1-2号金额],
SUM(Case When 日期 between '2006-06-03' and '2006-06-04' Then 金额 Else 0 End) As [1-2号金额]
就是加列的时候手工加确实不是很方便
Top
13 楼paoluo(一天到晚游泳的鱼)回复于 2006-07-01 15:48:10 得分 0
也寫個動態的,測試OK的
Declare @S Nvarchar(4000)
Set @S=''
Select @S=@S+N',SUM(Case When 日期='''+Convert(Varchar(10),日期,120)+N''' Then 金额 Else 0 End) As ['+Convert(Varchar(10),日期,120)+N'金额]'
From sell_tb Group By 日期
Select @S=N'Select A.客户名称'+@S+N' From client_tb A Left Join sell_tb B On A.客户ID=B.客户ID Group By A.客户名称'
--Select @S
EXEC(@S)
GO
Drop Table client_tb,sell_tb
--Result
/*
客户名称 2006-06-01金额 2006-06-02金额 2006-06-03金额 2006-06-04金额
客户A 200.0 100.0 100.0 100.0
客户B 100.0 100.0 100.0 0.0
客户C 200.0 100.0 0.0 100.0
客户D 100.0 200.0 0.0 0.0
客户E 0.0 200.0 100.0 100.0
客户F 0.0 100.0 0.0 100.0
*/Top
14 楼fcuandy(了此残生.)回复于 2006-07-01 15:51:47 得分 0
不能执行是因为你自己写错了吧.
仔细看
select @sql='select 客户名称'+@sql+' from client_tb a left join sell_tb b on a.客户ID=b.客户ID ...
这里
@sql=' select 客户名称' + @sql + ' ...Top




