交叉表查询(TRANSFORM)

sql中没有类似ACCESS的标准交叉表处理功能.   
  使用CASE和GROUP子句才是正确的选择(sql联机帮助也是这样说的,官方推荐)
动态列的问题,可以通过动态sql语句实现.

--参考:  
   
  if   exists   (select   *   from   dbo.sysobjects   where   id   =   object_id(N'[dbo].[p_qry]')   and   OBJECTPROPERTY(id,   N'IsProcedure')   =   1)  
  drop   procedure   [dbo].[p_qry]  
  GO  
   
  /*--生成交叉表的简单通用存储过程  
   
  根据指定的表名,纵横字段,统计字段,自动生成交叉表  
  并可根据需要生成纵横两个方向的合计  
   
  注意,横向字段数目如果大于纵向字段数目,将自动交换纵横字段  
  如果不要此功能,则去掉交换处理部分  
   
  --邹建   2004.06(引用请保留此信息)--*/  
   
  /*--调用示例  
   
  exec   p_qry   'syscolumns','id','colid','colid','name   like   ''s%''',1,1  
  --*/  
   
  create   proc   p_qry  
  @TableName   sysname, --表名  
  @纵轴   sysname, --交叉表最左面的列  
  @横轴   sysname, --交叉表最上面的列  
  @表体内容   sysname, --交叉表的数数据字段  
  @条件   varchar(1000),--查询的处理条件  
  @是否加横向合计   bit, --为1时在交叉表横向最右边加横向合计  
  @是否家纵向合计   bit --为1时在交叉表纵向最下边加纵向合计  
  as  
  declare   @s   nvarchar(4000),@sql   varchar(8000)  
   
  --规范条件  
  set   @条件=case   when   @条件<>''   then   '   where   ('+@条件+')'   else   ''   end  
   
  --判断横向字段是否大于纵向字段数目,如果是,则交换纵横字段  
  set   @s='declare   @a   sysname  
  if(select   case   when   count(distinct   ['+@纵轴+'])<count(distinct   ['+@横轴+'])   then   1   else   0   end  
  from   ['+@TableName+']   '+@条件+')=1  
  select   @a=@纵轴,@纵轴=@横轴,@横轴=@a'  
  exec   sp_executesql   @s  
  ,N'@纵轴   sysname   out,@横轴   sysname   out'  
  ,@纵轴   out,@横轴   out  
   
  --生成交叉表处理语句  
  set   @s='  
  set   @s=''''  
  select   @s=@s+'',[''+cast(['+@横轴+']   as   varchar)+'']=sum(case   ['+@横轴  
  +']   when   ''''''+cast(['+@横轴+']   as   varchar)+''''''   then   ['+@表体内容+']   else   0   end)''  
  from   ['+@TableName+']  
  '+@条件+'  
  group   by   ['+@横轴+']'  
  exec   sp_executesql   @s  
  ,N'@s   varchar(8000)   out'  
  ,@sql   out  
   
  --是否生成合计字段的处理  
  declare   @sum1   varchar(200),@sum2   varchar(200),@sum3   varchar(200)  
  select   @sum1=case   @是否加横向合计    
  when   1   then   ',[合计]=sum(['+@表体内容+'])'  
  else   ''   end  
  ,@sum2=case   @是否家纵向合计    
  when   1   then   '['+@纵轴+']=case   grouping(['  
  +@纵轴+'])   when   1   then   ''合计''   else   cast(['  
  +@纵轴+']   as   varchar)   end'  
  else   '['+@纵轴+']'   end  
  ,@sum3=case   @是否家纵向合计  
  when   1   then   '   with   rollup'  
  else   ''   end  
   
  --生成交叉表  
  exec('select   '+@sum2+@sql+@sum1+'  
  from   ['+@TableName+']  
  '+@条件+'  
  group   by   ['+@纵轴+']'+@sum3)  
  go  

CSDN中相关链接:

http://topic.csdn.net/t/20041229/10/3684609.html

http://topic.csdn.net/t/20050510/01/3993699.html

http://community.csdn.net/Expert/topic/4815/4815049.xml?temp=.2712061

http://topic.csdn.net/t/20050528/09/4041580.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQL Server 中,您可以使用 PIVOT 运算符来执行动态交叉。下面是使用 PIVOT 运算符编写的示例查询,该查询将 dbo_产品加工费用 中的数据转换为动态交叉: ``` SELECT * FROM ( SELECT 产品编号, 岗位, 加工费 FROM dbo_产品加工费用 WHERE 启用否 = 1 ) AS 原始数据 PIVOT ( AVG(加工费) FOR 岗位 IN ([岗位1], [岗位2], [岗位3]) -- 根据实际需求修改岗位列名 ) AS 动态交叉 ``` 在上面的查询中,我们使用了子查询来获取原始数据,并且使用 PIVOT 运算符将原始数据转换为动态交叉。在 PIVOT 运算符中,我们使用了 AVG 聚合函数来计算加工费之平均值,并且使用 FOR 关键字指定了岗位列的列名。 请注意,PIVOT 运算符要求您在查询中指定所有可能的列值。如果您的数据中岗位的值是不确定的,您可以使用动态 SQL生成查询,如下所示: ``` DECLARE @sql AS NVARCHAR(MAX) DECLARE @pivot_cols AS NVARCHAR(MAX) -- 生成动态 SQL SELECT @pivot_cols = COALESCE(@pivot_cols + ', ', '') + QUOTENAME(岗位) FROM dbo_产品加工费用 WHERE 启用否 = 1 SET @sql = ' SELECT * FROM ( SELECT 产品编号, 岗位, 加工费 FROM dbo_产品加工费用 WHERE 启用否 = 1 ) AS 原始数据 PIVOT ( AVG(加工费) FOR 岗位 IN (' + @pivot_cols + ') ) AS 动态交叉 ' -- 执行动态 SQL EXEC sp_executesql @sql ``` 在上面的代码中,我们首先使用 COALESCE 函数和 QUOTENAME 函数来生成动态 SQL 中的列名列,然后将其插入到查询字符串中。最后,我们使用 sp_executesql 存储过程来执行动态 SQL
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值