昨天被一從前同事問及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字符的文章﹐可惜我現在沒有找到﹐如果哪位有找到﹐或有解決方法﹐請不吝賜教﹗先謝了﹗