针对表各列进行Pivot/Unpivot的实现,通俗来讲,就是行转列,列转行的操作。
比如,
Date Name salary --- --- ----- 1/1/2012 jay 50 1/1/2012 ken 60 1/2/2012 ken 60 1/2/2012 jay 50 1/3/2012 jay 55 1/3/2012 lisa 80 ....想经过转换以后,得到下边的结果:
Date, ken, Jay, Lisa 1/1/2012 60 50 0 1/2/2012 60 50 0 1/3/2012 0 55 80一个支持Pivot/Unpivot语法的SQL语句,应该是下边这个样子的:
SELECT newPivot.* FROM (SELECT Date, Name, Salary FROM DBA.Salary ) AS source PIVOT ( SUM(source.Salary) FOR source.Name IN (‘Ken’ AS KEN, ‘Jay’ AS JAY, ‘Lisa’ AS LISA) ) AS newPivot Date KEN JAY LISA 1/1/2012 60 50 0 1/2/2012 60 50 0 1/3/2012 0 55 80
BEGIN DROP TABLE t1; EXCEPTION WHEN OTHERS THEN END; CREATE TABLE t1 ( c1 VARCHAR ( 10 ) NOT NULL, c2 VARCHAR ( 10 ) NOT NULL, c3 INTEGER NOT NULL, PRIMARY KEY ( c1, c2 ) ); INSERT t1 VALUES ( 'CA', 'Q1', 1000 ); INSERT t1 VALUES ( 'CA', 'Q2', 2000 ); INSERT t1 VALUES ( 'CA', 'Q3', 9000 ); INSERT t1 VALUES ( 'CA', 'Q4', 7000 ); INSERT t1 VALUES ( 'NY', 'Q1', 4000 ); INSERT t1 VALUES ( 'NY', 'Q2', 5000 ); INSERT t1 VALUES ( 'NY', 'Q3', 1000 ); INSERT t1 VALUES ( 'NY', 'Q4', 6000 ); INSERT t1 VALUES ( 'FL', 'Q1', 9000 ); INSERT t1 VALUES ( 'FL', 'Q2', 7000 ); INSERT t1 VALUES ( 'FL', 'Q3', 2000 ); INSERT t1 VALUES ( 'FL', 'Q4', 1000 ); INSERT t1 VALUES ( 'AZ', 'Q1', 5000 ); INSERT t1 VALUES ( 'AZ', 'Q2', 5000 ); INSERT t1 VALUES ( 'AZ', 'Q3', 1000 ); INSERT t1 VALUES ( 'AZ', 'Q4', 3000 ); INSERT t1 VALUES ( 'MA', 'Q1', 2000 ); INSERT t1 VALUES ( 'MA', 'Q2', 6000 ); INSERT t1 VALUES ( 'MA', 'Q3', 5000 ); INSERT t1 VALUES ( 'MA', 'Q4', 3000 ); COMMIT; SELECT * FROM t1 ORDER BY c1, c2;
1.
c2 AZ CA FL MA NY
2.
Q1 5000 1000 9000 2000 4000
3.
Q2 5000 2000 7000 6000 5000
4.
Q3 1000 9000 2000 5000 1000
5.
Q4 3000 7000 1000 3000 6000
BEGIN DECLARE @sql LONG VARCHAR; SET @sql = 'SELECT c2'; FOR f_fetch AS c_fetch NO SCROLL CURSOR FOR SELECT DISTINCT t1.c1 AS @c1 FROM t1 ORDER BY t1.c1 FOR READ ONLY DO SET @sql = STRING ( @sql, ', SUM ( ( IF t1.c1 = ''', @c1, ''' THEN 1 ELSE 0 ENDIF ) * t1.c3 ) AS "', @c1, '"' ); END FOR; SET @sql = STRING ( @sql, ' INTO #t1 FROM t1 GROUP BY c2' ); MESSAGE @sql TO CONSOLE; EXECUTE IMMEDIATE @sql; SELECT * FROM #t1 ORDER BY c2; -- pivot table END;
1.
c1 Q1 Q2 Q3 Q4
2.
AZ 5000 5000 1000 3000
3.
CA 1000 2000 9000 7000
4.
FL 9000 7000 2000 1000
5.
MA 2000 6000 5000 3000
6.
NY 4000 5000 1000 6000
BEGIN DECLARE @sql LONG VARCHAR; SET @sql = 'SELECT c1'; FOR f_fetch AS c_fetch NO SCROLL CURSOR FOR SELECT DISTINCT t1.c2 AS @c2 FROM t1 ORDER BY t1.c2 FOR READ ONLY DO SET @sql = STRING ( @sql, ', SUM ( ( IF t1.c2 = ''', @c2, ''' THEN 1 ELSE 0 ENDIF ) * t1.c3 ) AS "', @c2, '"' ); END FOR; SET @sql = STRING ( @sql, ' INTO #t1 FROM t1 GROUP BY c1' ); MESSAGE @sql TO CONSOLE; EXECUTE IMMEDIATE @sql; SELECT * FROM #t1 ORDER BY c1; -- pivot table END;
SELECT c2, SUM ( ( IF t1.c1 = 'AZ' THEN 1 ELSE 0 ENDIF ) * t1.c3 ) AS "AZ", SUM ( ( IF t1.c1 = 'CA' THEN 1 ELSE 0 ENDIF ) * t1.c3 ) AS "CA", SUM ( ( IF t1.c1 = 'FL' THEN 1 ELSE 0 ENDIF ) * t1.c3 ) AS "FL", SUM ( ( IF t1.c1 = 'MA' THEN 1 ELSE 0 ENDIF ) * t1.c3 ) AS "MA", SUM ( ( IF t1.c1 = 'NY' THEN 1 ELSE 0 ENDIF ) * t1.c3 ) AS "NY" INTO #t1 FROM t1 GROUP BY c2 SELECT c1, SUM ( ( IF t1.c2 = 'Q1' THEN 1 ELSE 0 ENDIF ) * t1.c3 ) AS "Q1", SUM ( ( IF t1.c2 = 'Q2' THEN 1 ELSE 0 ENDIF ) * t1.c3 ) AS "Q2", SUM ( ( IF t1.c2 = 'Q3' THEN 1 ELSE 0 ENDIF ) * t1.c3 ) AS "Q3", SUM ( ( IF t1.c2 = 'Q4' THEN 1 ELSE 0 ENDIF ) * t1.c3 ) AS "Q4" INTO #t1 FROM t1 GROUP BY c1