交叉表查詢(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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章