Oracle行转列、列转行的几种方法

时间:2024-03-22 10:43:25

一、行转列

我们的表结构和数据如下:

Oracle行转列、列转行的几种方法

1、使用PIVOT函数

        Oracle  11g之后,支持使用PIVOT实现行转列

函数说明:

        PIVOT(任意聚合函数  FOR  列名  IN(类型))

        其中,【聚合函数】聚合的字段,是需要转化为列值的字段;【列名】是需要转化为列标识的字段,【类型】即是需要的结果展示,【类型】中可以指定别名; IN中还可以指定子查询。

       针对我们如上例子,查询SQL应该为:

Oracle行转列、列转行的几种方法

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、如果直接使用【*】查询,会得不到查询结果:

Oracle行转列、列转行的几种方法

查询结果出错:

Oracle行转列、列转行的几种方法

 

2、即便是使用了嵌套查询,也必须写明查询字段

Oracle行转列、列转行的几种方法

查询结果出错:

Oracle行转列、列转行的几种方法

 

3、不可以直接使用WHERE语句

Oracle行转列、列转行的几种方法

 

4、PIVOT中的字段,是简单字段类型,不能加表别名

Oracle行转列、列转行的几种方法

Oracle行转列、列转行的几种方法

 

5、PIVOT函数中用到的字段,字段数据必须被查出

Oracle行转列、列转行的几种方法

 

2、使用 MAX 和 DECODE 函数

SQL图:

Oracle行转列、列转行的几种方法

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

结果展示:

Oracle行转列、列转行的几种方法

 

 

3、使用 CASE  WHEN  和  GROUP  BY

      这种方式是最常用的,比价容易理解。

SQL图:

Oracle行转列、列转行的几种方法

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

查询结果:

Oracle行转列、列转行的几种方法

 

 

二、列转行

1、使用对应的UNPIVOT函数

函数说明:

        UNPIVOT(自定义列名1【列的值】  FOR  自定义列名2【列名】  IN(【列名】))

        其中,【列的值】字段,是将我们的值字段转为行数据中的【自定义列名1】;【列名】是将我们的列标题字段转为行数据中的【自定义列名2】,【列名】即是转为行的列名。

 

        我们使用上面的结果为例子:

Oracle行转列、列转行的几种方法

Oracle行转列、列转行的几种方法

查询SQL图:

Oracle行转列、列转行的几种方法

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)
    )

查询结果:

Oracle行转列、列转行的几种方法

以后有其他方法,陆续更新-----------------------------------------------------------------