CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  MS-SQL Server >  应用实例

一个SQL查询环比问题,请帮忙看看

楼主maip(net)2006-07-01 14:09:54 在 MS-SQL Server / 应用实例 提问

--客户表:  
  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

相关问题

关键词

得分解答快速导航

  • 帖主:maip
  • paoluo
  • LouisXIV
  • fcuandy

相关链接

  • SQL Server类图书

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo