在SQL 2000中交叉表的應用

        昨天被一從前同事問及sql2K中交叉表的使用﹐回顧了一下sql﹐現根據QQ聊天記錄整理了一下﹐順便征求各位一個超過varchar型最大值8000后該如何實現的動態sql語句。
        建立測試環境﹕
CREATE   TABLE   [ ODBC_TEST ]  (
    
[ ID_Date ]   [ datetime ]   NULL  ,
    
[ Order_F ]   [ varchar ]  ( 20 ) COLLATE Chinese_PRC_CI_AS  NULL  ,
    
[ QTY ]   [ numeric ] ( 18 0 NULL
ON   [ PRIMARY ]
GO

insert   into  odbc_test
select   ' 2006-12-01 ' , ' aa ' , 10
union   all
select   ' 2006-12-02 ' , ' bb ' , 20
union   all
select   ' 2006-12-03 ' , ' cc ' , 30
union   all
select   ' 2007-01-01 ' , ' aa ' , 10
union   all
select   ' 2007-01-02 ' , ' bb ' , 20
union   all
select   ' 2007-01-03 ' , ' cc ' , 30

--select   *   from  ODBC_TEST
        他要的就是按年月分Oder_F統計QTY。當時我正在開緊電影﹐給出了第一個方案﹕
declare   @s   varchar ( 8000 )
set   @s = ' select ID_Date  '
select   @s = @s + ' , ' + Order_F + ' =sum(case when Order_F= ''' + Order_F + '''  then QTY else 0 end) '
from  ODBC_TEST
group   by  Order_F
set   @s = @s + '  from ODBC_TEST group by ID_Date order by ID_Date desc  '
--print   cast ( len ( @s as   varchar )
exec ( @s )
        結果﹕
ID_Date                                                aa                                       bb                                       cc                                       
-- ---------------------------------------------------- ---------------------------------------- ---------------------------------------- ---------------------------------------- 
2007 - 01 - 03   00 : 00 : 00.000                                  0                                          0                                          30
2007 - 01 - 02   00 : 00 : 00.000                                  0                                          20                                         0
2007 - 01 - 01   00 : 00 : 00.000                                  10                                         0                                          0
2006 - 12 - 03   00 : 00 : 00.000                                  0                                          0                                          30
2006 - 12 - 02   00 : 00 : 00.000                                  0                                          20                                         0
2006 - 12 - 01   00 : 00 : 00.000                                  10                                         0                                          0

        并沒有分年月﹐只是按日分而已﹐知道并沒有實現他的要求﹐在自已電腦中寫出了一個方案二﹕

create   table  #t (id_date  datetime ,order_f  varchar ( 20 ),qty numeric( 18 , 0 ))
insert   into  #t  select  id_date = case   when  ( day (id_date) <> 1 then   dateadd ( day , - day (id_date) + 1 , id_date)
                
else  id_date
                  
end
,order_f, qty 
from  ODBC_TEST

declare   @s   varchar ( 8000 )
set   @s = ' select ID_Date  '
select   @s = @s + ' , ' + Order_F + ' =sum(case when Order_F= ''' + Order_F + '''  then QTY else 0 end) '
from  #t
group   by  Order_F
set   @s = @s + '  from #t group by ID_Date order by ID_Date desc  '
-- print cast(len(@s) as varchar)
exec ( @s )
drop   table  #t
        結果如下﹕
ID_Date                                                aa                                       bb                                       cc                                       
-- ---------------------------------------------------- ---------------------------------------- ---------------------------------------- ---------------------------------------- 
2007 - 01 - 01   00 : 00 : 00.000                                  10                                         20                                         30
2006 - 12 - 01   00 : 00 : 00.000                                  10                                         20                                         30
        感覺怪怪的﹐并沒有達到預期想要的顯示效果﹐所以﹐我當時要他多等一會兒時間﹐這個時候﹐該從前同事發過來了他的方案代碼﹕
declare   @s   varchar ( 8000 )
set   @s = ' select Order_f,  '
select   @s = @s + ' sum(case left(convert(varchar(10),id_date,120),7) when  ''' + id_date + '''  then qty else 0 end) as  ''' +  id_date + ''' , '
from
(
select   distinct   left ( convert ( varchar ( 10 ),id_date, 120 ), 7 as   id_date  from  odbc_test ) a
set   @s   =   left ( @s , len ( @s ) - 1 + ' from odbc_test group by order_f order by order_f '
exec ( @s )
運行結果﹕
Order_f               2006 - 12                                    2007 - 01                                   
-- ------------------ ---------------------------------------- ---------------------------------------- 
aa                    10                                         10
bb                   
20                                         20
cc                   
30                                         30
faint....真有點暈﹐看來以后使用sql還是要從多方面著想﹐說不定什么時間就有靈感﹐使出不一樣而且簡潔輕便的實現方法﹐比傳統的思維要好很多。就比如說這個﹐唉﹐為什么不想一下日期型轉成字符型﹐然后取7位不就是年月了嗎?再次faint...
當然使用以上的動態SQL語句﹐如果數據過多﹐串聯起來的字符超過了8K,就會出錯的﹐曾記得CSDN上鄒健還是誰﹐有發表過如何解決這個超過8K字符的文章﹐可惜我現在沒有找到﹐如果哪位有找到﹐或有解決方法﹐請不吝賜教﹗先謝了﹗



你可能感兴趣的:(在SQL 2000中交叉表的應用)