一、行转列
我们的表结构和数据如下:
1、使用PIVOT函数
Oracle 11g之后,支持使用PIVOT实现行转列
函数说明:
PIVOT(任意聚合函数 FOR 列名 IN(类型))
其中,【聚合函数】聚合的字段,是需要转化为列值的字段;【列名】是需要转化为列标识的字段,【类型】即是需要的结果展示,【类型】中可以指定别名; IN中还可以指定子查询。
针对我们如上例子,查询SQL应该为:
SQL:
SELECT * FROM (
SELECT
A16.INTEREST_RATE_CD
,A16.DATA_DT
,A16.TERM
,A16.INTEREST_RATE
FROM FACT_FTP260_BSC_A16 A16
)
PIVOT(
SUM(INTEREST_RATE)
FOR TERM
IN ('1D' AS D1 ,'7D' AS D7 ,'14D' AS D14
,'1M' AS M1 ,'2M' AS M2 ,'6M' AS M6
,'9M' AS M9 ,'1Y' AS Y1 ,'2Y' AS Y2
,'3Y' AS Y3 ,'5Y' AS Y5 ,'7Y' AS Y7
,'10Y' AS Y10 ,'15Y' AS Y15 )
)
注意:
1、如果直接使用【*】查询,会得不到查询结果:
查询结果出错:
2、即便是使用了嵌套查询,也必须写明查询字段
查询结果出错:
3、不可以直接使用WHERE语句
4、PIVOT中的字段,是简单字段类型,不能加表别名
5、PIVOT函数中用到的字段,字段数据必须被查出
2、使用 MAX 和 DECODE 函数
SQL图:
SQL:
SELECT
A16.INTEREST_RATE_CD
,MAX(DECODE(A16.TERM, '1D', A16.INTEREST_RATE, 0 )) AS D1
,MAX(DECODE(A16.TERM, '7D', A16.INTEREST_RATE, 0 )) AS D7
,MAX(DECODE(A16.TERM, '14D', A16.INTEREST_RATE, 0 )) AS D14
,MAX(DECODE(A16.TERM, '1M', A16.INTEREST_RATE, 0 )) AS M1
,MAX(DECODE(A16.TERM, '2M', A16.INTEREST_RATE, 0 )) AS M2
,MAX(DECODE(A16.TERM, '3M', A16.INTEREST_RATE, 0 )) AS M3
,MAX(DECODE(A16.TERM, '6M', A16.INTEREST_RATE, 0 )) AS M6
,MAX(DECODE(A16.TERM, '9M', A16.INTEREST_RATE, 0 )) AS M9
,MAX(DECODE(A16.TERM, '1Y', A16.INTEREST_RATE, 0 )) AS Y1
,MAX(DECODE(A16.TERM, '2Y', A16.INTEREST_RATE, 0 )) AS Y2
,MAX(DECODE(A16.TERM, '3Y', A16.INTEREST_RATE, 0 )) AS Y3
,MAX(DECODE(A16.TERM, '5Y', A16.INTEREST_RATE, 0 )) AS Y5
,MAX(DECODE(A16.TERM, '7Y', A16.INTEREST_RATE, 0 )) AS Y7
,MAX(DECODE(A16.TERM, '10Y', A16.INTEREST_RATE, 0 )) AS Y10
,MAX(DECODE(A16.TERM, '15Y', A16.INTEREST_RATE, 0 )) AS Y15
FROM FACT_FTP260_BSC_A16 A16
GROUP BY
A16.INTEREST_RATE_CD
结果展示:
3、使用 CASE WHEN 和 GROUP BY
这种方式是最常用的,比价容易理解。
SQL图:
SQL:
SELECT
A16.INTEREST_RATE_CD
,SUM(CASE TERM WHEN '1D' THEN A16.INTEREST_RATE ELSE 0 END) AS D1
,SUM(CASE TERM WHEN '7D' THEN A16.INTEREST_RATE ELSE 0 END) AS D7
,SUM(CASE TERM WHEN '14D' THEN A16.INTEREST_RATE ELSE 0 END) AS D14
,SUM(CASE TERM WHEN '1M' THEN A16.INTEREST_RATE ELSE 0 END) AS M1
,SUM(CASE TERM WHEN '2M' THEN A16.INTEREST_RATE ELSE 0 END) AS M2
,SUM(CASE TERM WHEN '3M' THEN A16.INTEREST_RATE ELSE 0 END) AS M3
,SUM(CASE TERM WHEN '6M' THEN A16.INTEREST_RATE ELSE 0 END) AS M6
,SUM(CASE TERM WHEN '9M' THEN A16.INTEREST_RATE ELSE 0 END) AS M9
,SUM(CASE TERM WHEN '1Y' THEN A16.INTEREST_RATE ELSE 0 END) AS Y1
,SUM(CASE TERM WHEN '2Y' THEN A16.INTEREST_RATE ELSE 0 END) AS Y2
,SUM(CASE TERM WHEN '3Y' THEN A16.INTEREST_RATE ELSE 0 END) AS Y3
,SUM(CASE TERM WHEN '5Y' THEN A16.INTEREST_RATE ELSE 0 END) AS Y5
,SUM(CASE TERM WHEN '7Y' THEN A16.INTEREST_RATE ELSE 0 END) AS Y7
,SUM(CASE TERM WHEN '10Y' THEN A16.INTEREST_RATE ELSE 0 END) AS Y10
,SUM(CASE TERM WHEN '15Y' THEN A16.INTEREST_RATE ELSE 0 END) AS Y15
FROM FACT_FTP260_BSC_A16 A16
GROUP BY
A16.INTEREST_RATE_CD
查询结果:
二、列转行
1、使用对应的UNPIVOT函数
函数说明:
UNPIVOT(自定义列名1【列的值】 FOR 自定义列名2【列名】 IN(【列名】))
其中,【列的值】字段,是将我们的值字段转为行数据中的【自定义列名1】;【列名】是将我们的列标题字段转为行数据中的【自定义列名2】,【列名】即是转为行的列名。
我们使用上面的结果为例子:
查询SQL图:
SQL:
WITH TEMP AS (
SELECT * FROM (
SELECT A16.INTEREST_RATE_CD, A16.DATA_DT, A16.TERM, A16.INTEREST_RATE
FROM FACT_FTP260_BSC_A16 A16
)
PIVOT(
SUM(INTEREST_RATE)
FOR TERM
IN ('1D' AS D1, '7D' AS D7, '14D' AS D14, '1M' AS M1, '2M' AS M2
,'3M' AS M3, '6M' AS M6, '9M' AS M9, '1Y' AS Y1, '2Y' AS Y2
,'3Y' AS Y3, '5Y' AS Y5, '7Y' AS Y7, '10Y' AS Y10, '15Y' AS Y15 )
)
)
SELECT *
FROM TEMP T
UNPIVOT(
"利率值INTEREST_RATE"
FOR "产品编码TERM"
IN(D1, D7, D14, M1, M2, M3, M6, M9,
Y1, Y2, Y3, Y5, Y7, Y10, Y15)
)
查询结果:
以后有其他方法,陆续更新-----------------------------------------------------------------