Oracle 10g 和SQL Server 2000还没有提供专门的行列转换函数,而SQL Server 2005和Oracle 11g都可以直接用PIVOT/UNPIVOT进行方便的转换。
当时看过SQL Server 2005 Inside T SQL Querying那本书,里面讲到SQL Server 2005及以前的版本中如何实现行列转行,原书的代码如下:
1
-- Listing 6-4: Creating and Populating the Orders Table2
USE tempdb;3
GO4
IF OBJECT_ID('dbo.Orders') IS NOT NULL5
DROP TABLE dbo.Orders;6
GO7
CREATE TABLE dbo.Orders8
(9
orderid int NOT NULL PRIMARY KEY NONCLUSTERED,10
orderdate datetime NOT NULL,11
empid int NOT NULL,12
custid varchar(5) NOT NULL,13
qty int NOT NULL14
);15
CREATE UNIQUE CLUSTERED INDEX idx_orderdate_orderid16
ON dbo.Orders(orderdate, orderid);17
INSERT INTO dbo.Orders(orderid, orderdate, empid, custid, qty)18
VALUES(30001, '20020802', 3, 'A', 10);19
INSERT INTO dbo.Orders(orderid, orderdate, empid, custid, qty)20
VALUES(10001, '20021224', 1, 'A', 12);21
INSERT INTO dbo.Orders(orderid, orderdate, empid, custid, qty)22
VALUES(10005, '20021224', 1, 'B', 20);23
INSERT INTO dbo.Orders(orderid, orderdate, empid, custid, qty)24
VALUES(40001, '20030109', 4, 'A', 40);25
INSERT INTO dbo.Orders(orderid, orderdate, empid, custid, qty)26
VALUES(10006, '20030118', 1, 'C', 14);27
INSERT INTO dbo.Orders(orderid, orderdate, empid, custid, qty)28
VALUES(20001, '20030212', 2, 'B', 12);29
INSERT INTO dbo.Orders(orderid, orderdate, empid, custid, qty)30
VALUES(40005, '20040212', 4, 'A', 10);31
INSERT INTO dbo.Orders(orderid, orderdate, empid, custid, qty)32
VALUES(20002, '20040216', 2, 'C', 20);33
INSERT INTO dbo.Orders(orderid, orderdate, empid, custid, qty)34
VALUES(30003, '20040418', 3, 'B', 15);35
INSERT INTO dbo.Orders(orderid, orderdate, empid, custid, qty)36
VALUES(30004, '20020418', 3, 'C', 22);37
INSERT INTO dbo.Orders(orderid, orderdate, empid, custid, qty)38
VALUES(30007, '20020907', 3, 'D', 30);39
GO40
-- Aggregating Data, Pre-2005 Solution, Total Qty41
SELECT custid,42
SUM(CASE WHEN orderyear = 2002 THEN qty END) AS [2002],43
SUM(CASE WHEN orderyear = 2003 THEN qty END) AS [2003],44
SUM(CASE WHEN orderyear = 2004 THEN qty END) AS [2004]45
FROM (SELECT custid, YEAR(orderdate) AS orderyear, qty46
FROM dbo.Orders) AS D47
GROUP BY custid;48
GO49

本人照葫芦画瓢,将上面的代码迁移到Oracle 10g中,代码如下:
1
CREATE TABLE Orders2
(3
orderid int NOT NULL PRIMARY KEY ,4
orderdate date NOT NULL,5
empid int NOT NULL,6
custid varchar2(5) NOT NULL,7
qty int NOT NULL8
);9
10
INSERT INTO Orders11
(orderid, orderdate, empid, custid, qty)12
VALUES13
(10001, to_date('20021224', 'yyyymmdd'), 1, 'A', 12);14
INSERT INTO Orders15
(orderid, orderdate, empid, custid, qty)16
VALUES17
(10005, to_date('20021224', 'yyyymmdd'), 1, 'B', 20);18
INSERT INTO Orders19
(orderid, orderdate, empid, custid, qty)20
VALUES21
(40001, to_date('20030109', 'yyyymmdd'), 4, 'A', 40);22
INSERT INTO Orders23
(orderid, orderdate, empid, custid, qty)24
VALUES25
(10006, to_date('20030118', 'yyyymmdd'), 1, 'C', 14);26
INSERT INTO Orders27
(orderid, orderdate, empid, custid, qty)28
VALUES29
(20001, to_date('20030212', 'yyyymmdd'), 2, 'B', 12);30
INSERT INTO Orders31
(orderid, orderdate, empid, custid, qty)32
VALUES33
(40005, to_date('20040212', 'yyyymmdd'), 4, 'A', 10);34
INSERT INTO Orders35
(orderid, orderdate, empid, custid, qty)36
VALUES37
(20002, to_date('20040216', 'yyyymmdd'), 2, 'C', 20);38
INSERT INTO Orders39
(orderid, orderdate, empid, custid, qty)40
VALUES41
(30003, to_date('20040418', 'yyyymmdd'), 3, 'B', 15);42
INSERT INTO Orders43
(orderid, orderdate, empid, custid, qty)44
VALUES45
(30004, to_date('20020418', 'yyyymmdd'), 3, 'C', 22);46
INSERT INTO Orders47
(orderid, orderdate, empid, custid, qty)48
VALUES49
(30007, to_date('20020907', 'yyyymmdd'), 3, 'D', 30);50
51
SELECT custid,52
SUM(CASE WHEN orderyear = '2002' THEN qty END) as 二零零二,53
SUM(CASE WHEN orderyear = '2003' THEN qty END)as 二零零三,54
SUM(CASE WHEN orderyear = '2004' THEN qty END)as 二零零四55
FROM (SELECT custid, to_char(orderdate,'yyyy')AS orderyear, qty56
FROM Orders) D57
GROUP BY custid; 算是一种行列转行的方案吧,O(∩_∩)O~