CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  MS-SQL Server >  基础类

问题没解决,邹建,大力,马克进来看看,好吗?谢谢了!!

楼主Judges(随便什么都可以么?)2003-12-03 13:40:11 在 MS-SQL Server / 基础类 提问

有财务表:  
  编号(int   not   null)     往来单位   (int)   项目(int)     金额(money)     日期(datetime)  
  有公司信息表  
  编号(int   not   null)     公司全称(varchar(100))     地区(varchar(50))...  
  有项目信息表  
  编号(int   not   null)     项目名称(varchar(100))...  
   
  其中财务表中的往来单位为外键,对应公司信息表中的编号,项目对应项目信息表中的项目编号。  
   
  现在需要生成财务报表。如下  
  编号   往来单位     项目1     项目2     ...     项目n      
    1               A             500         600       ...         0  
    2               B             ...         ...       ...       ...  
  ...           ...           ...         ...       ...       ...  
   
  查询条件为财务日期,公司所在地区,项目三个条件。怎么实现?最好是不使用存储过程。  
   
  谢谢了!!    
  问题点数:80、回复次数:13Top

1 楼pengdali()回复于 2003-12-03 13:51:04 得分 35

不用过程:  
   
  交叉数据报表  
  有时候需要旋转结果以便在水平方向显示列,而在垂直方向显示行。这就是所谓的创建   PivotTable®、创建交叉数据报表或旋转数据。  
   
  假定有一个表   Pivot,其中每季度占一行。对   Pivot   的   SELECT   操作在垂直方向上列出这些季度:  
   
  Year             Quarter             Amount  
  ----             -------             ------  
  1990             1                       1.1  
  1990             2                       1.2  
  1990             3                       1.3  
  1990             4                       1.4  
  1991             1                       2.1  
  1991             2                       2.2  
  1991             3                       2.3  
  1991             4                       2.4  
   
  生成报表的表必须是这样的,其中每年占一行,每个季度的数值显示在一个单独的列中,如:  
   
  Year  
    Q1  
    Q2  
    Q3  
    Q4  
     
  1990  
    1.1  
    1.2  
    1.3  
    1.4  
     
  1991  
    2.1  
    2.2  
    2.3  
    2.4  
     
   
   
  下面的语句用于创建   Pivot   表并在其中填入第一个表中的数据:  
   
  USE   Northwind  
  GO  
   
  CREATE   TABLE   Pivot  
  (   Year             SMALLINT,  
      Quarter       TINYINT,    
      Amount             DECIMAL(2,1)   )  
  GO  
  INSERT   INTO   Pivot   VALUES   (1990,   1,   1.1)  
  INSERT   INTO   Pivot   VALUES   (1990,   2,   1.2)  
  INSERT   INTO   Pivot   VALUES   (1990,   3,   1.3)  
  INSERT   INTO   Pivot   VALUES   (1990,   4,   1.4)  
  INSERT   INTO   Pivot   VALUES   (1991,   1,   2.1)  
  INSERT   INTO   Pivot   VALUES   (1991,   2,   2.2)  
  INSERT   INTO   Pivot   VALUES   (1991,   3,   2.3)  
  INSERT   INTO   Pivot   VALUES   (1991,   4,   2.4)  
  GO  
   
  下面是用于创建旋转结果的   SELECT   语句:  
   
  SELECT   Year,    
          SUM(CASE   Quarter   WHEN   1   THEN   Amount   ELSE   0   END)   AS   Q1,  
          SUM(CASE   Quarter   WHEN   2   THEN   Amount   ELSE   0   END)   AS   Q2,  
          SUM(CASE   Quarter   WHEN   3   THEN   Amount   ELSE   0   END)   AS   Q3,  
          SUM(CASE   Quarter   WHEN   4   THEN   Amount   ELSE   0   END)   AS   Q4  
  FROM   Northwind.dbo.Pivot  
  GROUP   BY   Year  
  GO  
   
  该   SELECT   语句还处理其中每个季度占多行的表。GROUP   BY   语句将   Pivot   中一年的所有行合并成一行输出。当执行分组操作时,SUM   聚合中的   CASE   函数的应用方式是这样的:将每季度的   Amount   值添加到结果集的适当列中,在其它季度的结果集列中添加   0。  
   
  如果该   SELECT   语句的结果用作电子表格的输入,那么电子表格将很容易计算每年的合计。当从应用程序使用   SELECT   时,可能更易于增强   SELECT   语句来计算每年的合计。例如:  
   
  SELECT   P1.*,   (P1.Q1   +   P1.Q2   +   P1.Q3   +   P1.Q4)   AS   YearTotal  
  FROM   (SELECT   Year,  
                            SUM(CASE   P.Quarter   WHEN   1   THEN   P.Amount   ELSE   0   END)   AS   Q1,  
                            SUM(CASE   P.Quarter   WHEN   2   THEN   P.Amount   ELSE   0   END)   AS   Q2,  
                            SUM(CASE   P.Quarter   WHEN   3   THEN   P.Amount   ELSE   0   END)   AS   Q3,  
                            SUM(CASE   P.Quarter   WHEN   4   THEN   P.Amount   ELSE   0   END)   AS   Q4  
            FROM   Pivot   AS   P  
            GROUP   BY   P.Year)   AS   P1  
  GO  
   
  带有   CUBE   的   GROUP   BY   和带有   ROLLUP   的   GROUP   BY   都计算与本例显示相同的信息种类,但格式稍有不同。  
  Top

2 楼txlicenhe(马可)回复于 2003-12-03 13:51:45 得分 0

http://expert.csdn.net/Expert/topic/2440/2440306.xml?temp=.6941645  
    [交流]行列转换Top

3 楼pengdali()回复于 2003-12-03 13:53:56 得分 0

declare   @sql   varchar(8000)  
  set   @sql   =   'select   a.编号,b.公司全称'  
  select   @sql   =   @sql   +   ',sum(case   a.项目   when   '''+cast(编号   as   varchar(10))+'''   then   a.金额   else   0   end)   ['+项目名称+']'  
      from   项目信息表  
  select   @sql   =   @sql+'   from   财务表   a,公司信息表   b   where   a.往来单位=b.编号   group   by   a.编号,b.编号,b.公司全称'  
   
  exec(@sql)  
  go  
  Top

4 楼txlicenhe(马可)回复于 2003-12-03 13:54:48 得分 0

declare   @sql   varchar(8000)  
  set   @sql   =   'select   编号'  
  select   @sql   =   @sql   +   ',sum(case   项目   when   '''+cast(项目   as   varchar)+'''   then   金额   end)   ['+cast(项目   as   varchar)+']'  
    from   (select   distinct   项目   from   财务表)   as   a  
  select   @sql   =   @sql+'   from   财务表     group   by   编号'  
  exec(@sql)  
   
  Top

5 楼pengdali()回复于 2003-12-03 13:54:51 得分 0

不用过程你必须一条一条的写case。动态得话只要上面就可以了。Top

6 楼CrazyFor(冬眠的鼹鼠)回复于 2003-12-03 13:56:27 得分 5

参考:  
  create   table   #(a   varchar(100),b   int)  
  insert   #   values('aa',11)  
  insert   #   values('bb',1)  
  insert   #   values('aa',45)  
  insert   #   values('cc',81)  
  insert   #   values('a',11)  
  insert   #   values('aay',561)  
  insert   #   values('a',14)  
   
  declare   @sql   varchar(8000)  
  set   @sql   =   'select   '  
  select   @sql   =   @sql   +   'sum(case   a   when   '''+a+'''    
                                                      then   b   else   0   end)   '+a+'的数量,'  
      from   (select   distinct   a   from   #)   as   a  
   
  select   @sql   =   left(@sql,len(@sql)-1)   +   '   from   #'  
   
  exec(@sql)  
   
  drop   table   #Top

7 楼victorycyz(--)回复于 2003-12-03 14:19:27 得分 0

另类办法:  
   
  把表链接到Access库中,可利用Jet连接方便地写交叉查询:  
   
  TRANSFORM   汇总字段   AS   值  
  SELECT   字段列表,汇总字段  
  FROM   表  
  GROUP   BY   分组字段  
  PIVOT   标题字段Top

8 楼Judges(随便什么都可以么?)回复于 2003-12-03 14:44:46 得分 0

在查询管理器里是可以了     写到asp中去是不是可以直接使用sql的写法     还是要变化一下的Top

9 楼pengdali()回复于 2003-12-03 14:53:14 得分 0

你直接调存储过程呀。Top

10 楼pengdali()回复于 2003-12-03 14:53:55 得分 5

1,调用没有参数的存储过程  
  <%  
  set   conn=server.CreateObject("adodb.connection")  
  set   cmd=server.CreateObject("adodb.command")  
  strconn="dsn=pubs;uid=sa;pwd"  
   
  conn.Open   strconn  
  set   cmd.ActiveNonnection=conn  
   
  cmd.CommandText="{call   nono}"  
   
  ''set   rs=cmc.exe   或者cmd.execute  
   
  set   rs=cmd.Execute()  
   
  %>  
  2,一个输入的参数的存储过程  
  <%  
  set   conn=server.CreateObject("adodb.connection")  
  set   cmd=server.CreateObject("adodb.command")  
  strconn="dsn=pubs;uid=sa;pwd"  
   
  conn.Open   strconn  
  set   cmd.ActiveConnection=conn  
   
  cmd.CommandText="{call   oneinput(?)}"  
  cmd.Parameters.Append   cmd.CreateParameter("@aaa",adInteger   ,adParamInput   )  
  cmd("@aaa")=100  
   
  cmd.Execute()  
   
  %>  
  3,一个输入参数和一个输出的参数  
  <%  
  set   conn=server.CreateObject("adodb.connection")  
  set   cmd=server.CreateObject("adodb.command")  
  strconn="dsn=pubs;uid=sa;pwd"  
   
  conn.Open   strconn  
  set   cmd.ActiveConnection=conn  
   
  cmd.CommandText   =   "{call   oneinout(?,?)}"  
  cmd.Parameters.Append   cmd.CreateParameter("@aaa",adInteger,adParamInput)  
  cmd("@aaa")=10  
  cmd.Parameters.Append   cmd.CreateParameter("@bbb",adInteger,adParamOutput)  
   
  cmd.Execute()  
   
  bbb=cmd("@bbb")  
  %>  
  4,一个输入参数,一个输出参数,和一个返回值  
  <%  
  set   conn=server.CreateObject("adodb.connection")  
  set   cmd=server.CreateObject("adodb.command")  
  strconn="dsn=pubs;uid=sa;pwd"  
   
  conn.Open   strconn  
  set   cmd.ActiveConnection=conn  
   
  cmd.CommandText="{?=call   onereturn(?,?)}"  
   
  cmd.Parameters.Append   cmd.CreateParameter("@return_value",adInteger,adParamReturnValue   )  
  cmd.Parameters.Append   cmd.CreateParameter("@aaa",adInteger,adParamInput   )  
  cmd("@aaa")=10  
  cmd.Parameters.Append   cmd.CreateParameter("@bbb",adInteger,adParamOutput)  
   
  cmd.Execute()  
   
  bbb=cmd("@bbb")  
  rrr=cmd("@return_value")  
  %>    
  Top

11 楼zjcxc(邹建)回复于 2003-12-03 16:56:33 得分 35

--这种情况最好用存储过程  
  create   proc   p_qry  
  @财务日期   datetime,  
  @公司所在地区   varchar(50),  
  @项目   varchar(5000)  
  as  
  set   nocount   on  
  declare   @s   varchar(8000),@tj   varchar(1000)  
  select   @s=''  
   
  select   @s=@s+',['+项目名称=']=sum(case   a.项目   when   '  
  +cast(编号   as   varchar)+'   then   a.金额   else   0   end)'  
  from   项目信息表   where   charindex(','+项目名称+',',','+@项目+',')>0  
   
  set   @tj='   where   a.日期='''+convert(varchar(10),@财务日期,120)  
  +'''   and   b.地区='''+@公司所在地区  
  +'''   and   项目   in('''+stuff(@项目,',',''',''')+''')'  
   
  --查询  
  exec('select   a.编号,b.往来单位'+@s+'  
  from   财务表   a  
  join   公司信息表   b   on   a.往来单位=b.编号  
  join   项目信息表   c   on   a.项目=c.编号  
  '+@tj)  
  set   nocount   off  
  go  
  Top

12 楼Judges(随便什么都可以么?)回复于 2003-12-12 16:51:06 得分 0

在使用的时候出现问题:  
   
  select   @s=@s+',['+项目名称+']=sum(case   a.项目   when   '  
  +cast(编号   as   varchar)+'   then   a.金额   else   0   end)'  
  from   项目信息表   where   charindex(','+项目名称+',',','+@项目+',')>0  
   
  这句中出现:  
  服务器:   消息   207,级别   16,状态   3,过程   p_qry,行   12  
  列名   '业务种类1'   无效。  
   
  的错误提示  
   
  请教     呵呵!!Top

13 楼zjcxc(邹建)回复于 2003-12-12 17:03:45 得分 0

你是怎么调用的?  
   
  上面存储过程的调用方法是:  
   
   
  --这种情况最好用存储过程  
  exec   p_qry   '2003-01-01','广东','项目1,项目2'  
  Top

相关问题

  • 高手进来帮帮忙啊。非常急,大力、邹建
  • 从前有彭大力, 现在有邹建, 我是新来的! 呵.
  • 高手进来帮帮忙啊。非常急,大力、邹建 近来看看
  • 请教邹建、大力等各位高手:时间类型的毫秒数处理?
  • 再开一贴:邹建,大力,朱二,小刀等高手进!!!链接服务器的问题!!!!
  • 请教邹建。
  • 邹建请进
  • 求助邹建!!!
  • 邹建接分
  • 邹建接分

关键词

  • 项目
  • 存储过程
  • 字段
  • 语句
  • 报表
  • 查询
  • pivot
  • 财务
  • 表
  • 编号

得分解答快速导航

  • 帖主:Judges
  • pengdali
  • CrazyFor
  • pengdali
  • zjcxc

相关链接

  • SQL Server类图书

广告也精彩

反馈

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