前言

行转列,依照实际的业务需求,在Oracle数据库中创建相应的透视/交叉表。推荐阅读官方文档 透视和逆透视

透视(行转列)

原查询语句为:

1
2
3
4
5
6
7
SELECT p.Prod_date,p.INDEX_NAME ,p.ITEM_VALUE 
FROM PC_SPL_REPORT_INDEX_ITEM p
WHERE 1 = 1
AND p.REPORT_ID = '16673814706151363'
AND p.INDEX_NAME IN ('商品量','工业产量','销售量')
AND to_char(p.Prod_date,'yyyy') = to_char(sysdate,'yyyy')
ORDER BY p.Prod_date,p.INDEX_NAME

查询结果为:

| Prod_date | INDEX_NAME | ITEM_VALUE |
| :—-: | :—-: | :—-: |
| 2023-01-01 | 商品量 | 6154086 |
| 2023-01-01 | 工业产量 | 6308353 |
| 2023-01-01 | 销售量 | 7632859 |
| 2023-01-02 | 商品量 | 6260378 |
| 2023-01-02 | 工业产量 | 6341415 |
| 2023-01-02 | 销售量 | 7293744 |
| 2023-01-03 | 商品量 | 6396051 |
| 2023-01-03 | 工业产量 | 6350111 |
| 2023-01-03 | 销售量 | 7571332 |

我们需要把Index_Name字段横行排列,形成新的交叉表,以方便我们在后续的报表上使用,这个时候就要使用到pivot函数。

1
2
3
4
5
6
7
8
9
10
11
12
SELECT * FROM (
SELECT p.Prod_date,p.INDEX_NAME ,p.ITEM_VALUE
FROM PC_SPL_REPORT_INDEX_ITEM p
WHERE 1 = 1
AND p.REPORT_ID = '16673814706151363'
AND p.INDEX_NAME IN ('商品量','工业产量','销售量')
AND to_char(p.Prod_date,'yyyy') = to_char(sysdate,'yyyy')
ORDER BY p.Prod_date,p.INDEX_NAME
)PIVOT
(
SUM(ITEM_VALUE) AS VALUE FOR INDEX_NAME IN ('商品量' AS SPL,'工业产量' AS GYCL,'销售量' AS XSL )
)

查询后的结果为:

| Prod_date | SPL_VALUE | GYCL_VALUE | XSL_VALUE |
| :—-: | :—-: | :—-: | :—-: |
| 2023-01-01 |6154086 |6308353 | 7632859 |
| 2023-01-02 |6260378 |6341415 | 7293744 |
| 2023-01-03 |6396051 |6350111 | 7571332 |

结语

除了透视pivot函数Oracle 11g还提供了反透视unpivot函数,可以将列转换为行。具体的使用还得看实际的业务场景了。