轉自:http://blog.csdn.net/yiyunstone/archive/2009/05/15/4189728.aspx
爲簡化說明應用,假設轉置前,數據庫中表有三列:日期,國家,數量。如下表:
國家 |
日期 |
數量 |
B |
2005-8-8 |
40.00 |
B |
2005-8-7 |
6.00 |
C |
2005-8-8 |
77.00 |
A |
2005-8-9 |
33.00 |
A |
2005-8-8 |
9.00 |
C |
2005-8-7 |
21.00 |
要求轉置爲列標題爲日期,國家,並按合計數量從左到右排列國家名稱。
如下表:
日期 |
C |
B |
A |
2005-8-7 |
21 |
6 |
0 |
2005-8-8 |
77 |
40 |
9 |
2005-8-9 |
0 |
0 |
33 |
合計 |
98 |
46 |
42 |
思路:
先在裝置前,將國家按合計數量降序排列。形如:
國家 |
日期 |
數量 |
合計 |
C |
2005-8-7 |
21.00 |
98.00 |
C |
2005-8-8 |
77.00 |
98.00 |
B |
2005-8-8 |
40.00 |
46.00 |
B |
2005-8-7 |
6.00 |
46.00 |
A |
2005-8-9 |
33.00 |
42.00 |
A |
2005-8-8 |
9.00 |
42.00 |
再進行動態轉置。裝置的基本思路是拼SQL,
第一部分是,SELECT CALLDATE,
第二部分是,sum(case country=’A’ THEN count else 0 end ) as ‘A’ 的國家字段
第三部分是 from 之後的語句。
關鍵在於不要將第二部分的case語句寫死,按數據庫中國家的出現的順序來拼這個 case語句。
用如下SQL形成一個SQL的中間表:
內容爲:
,sum(case when COUNTRY=C then CallCount else 0 end) "C" |
,sum(case when COUNTRY=B then CallCount else 0 end) "B" |
,sum(case when COUNTRY=A then CallCount else 0 end) "A" |
將該中間表的內容逐行讀出,拼爲SQL即可。
附:生成動態case語句的SQL:
SELECT ',sum(case when COUNTRY='
|| COUNTRY
|| ' then CallCount else 0 end)'
|| ' "'
|| COUNTRY
|| '"' c2
FROM (
select a.*,b.heji
from before1 a
left join
(
select country, sum(count) as heji
from before1
group by country
) b
on a.country=b.country
order by heji desc
)
GROUP BY COUNTRY;
附準備數據SQL :
CREATE TABLE before1(
country VARCHAR2(2 BYTE),
calldate DATE,
count INTEGER
);
INSERT INTO before1( country, calldate, count)
VALUES ('B', TO_DATE ('08/08/2005', 'MM/DD/YYYY'), 40);
NSERT INTO before1( country, calldate, count)
VALUES ('B', TO_DATE ('08/07/2005', 'MM/DD/YYYY'), 6);
INSERT INTO before1( country, calldate, count)
VALUES ('C', TO_DATE ('08/08/2005', 'MM/DD/YYYY'), 77);
INSERT INTO before1( country, calldate, count)
VALUES ('A', TO_DATE ('08/09/2005', 'MM/DD/YYYY'), 33);
INSERT INTO before1( country, calldate, count)
VALUES ('A', TO_DATE ('08/08/2005', 'MM/DD/YYYY'), 9);
INSERT INTO before1( country, calldate, count)
VALUES ('C', TO_DATE ('08/07/2005', 'MM/DD/YYYY'), 21);