ORACLE行轉列、列轉行實現方式及案例
- 行轉列
- 案例
- 方式1.PIVOT
- 方式2.MAX和DECODE
- 方式3.CASE WHEN和GROUP BY
- 列轉行
- 案例
- 方式1.UNPIVOT
- 方式2.UNION ALL
行轉列
案例
假設我們有一個名為sales的表,其中包含了產品銷售數據。表中有三列:product(產品名稱)、year(年份)和amount(銷售額)。表中的數據如下:
將這個表中的數據進行行轉列,使得每一行表示一個產品,每一列表示一年的銷售額。
使得得到以下結果:
方式1.PIVOT
PIVOT是Oracle 11g之后引入的一種用于行列轉換的函數。它可以將查詢結果中的行數據轉換為列數據,從而實現行列轉換。PIVOT函數的基本語法如下:
SELECT ...
FROM ...
PIVOT (aggregate_function(column_to_aggregate)FOR column_to_pivotIN (list_of_values))
其中,aggregate_function是一個聚合函數,如SUM、MAX、MIN等;column_to_aggregate是要進行聚合的列;column_to_pivot是要進行行列轉換的列;list_of_values是要轉換為列的值的列表。
實現案例所示效果可以通過如下方式:
SELECT *
FROM sales
PIVOT (SUM(amount) FOR year IN (2018, 2019, 2020));
方式2.MAX和DECODE
DECODE 可以根據條件返回不同的值。DECODE 函數的基本語法如下:
DECODE(expression, search1, result1,search2, result2, ..., default)
其中,expression 是要進行比較的表達式;search1、search2 等是要進行比較的值;result1、result2 等是當表達式與對應的搜索值相等時返回的結果;default 是當表達式與所有搜索值都不相等時返回的默認值。
若要實現案例的效果可以通過以下方式:
SELECT product,MAX(DECODE(year, 2018, amount)) AS "2018",MAX(DECODE(year, 2019, amount)) AS "2019",MAX(DECODE(year, 2020, amount)) AS "2020"
FROM sales
GROUP BY product;
注意:這里取的是每年數據的最大值,每年每產品指只會一條,而方式3是取總和
方式3.CASE WHEN和GROUP BY
SELECT product,SUM(CASE WHEN year = 2018 THEN amount END) AS "2018",SUM(CASE WHEN year = 2019 THEN amount END) AS "2019",SUM(CASE WHEN year = 2020 THEN amount END) AS "2020"
FROM sales
GROUP BY product;
注意:這里取的是每年數據的總和,每年每產品的總和,而方式2是取最大的一條
列轉行
案例
與行轉列的案例相反假設我們有一個名為sales的表,其中包含了產品銷售數據。表中有四列:product(產品名稱)、2018(2018年銷售額)、2019(2019年銷售額)和2020(2020年銷售額)。表中的數據如下:
現在我們想要將這個表中的數據進行列轉行,使得每一行表示一個產品在某一年的銷售額。
實現效果如下:
方式1.UNPIVOT
UNPIVOT是Oracle中用于實現列轉行的函數,基本語法如下:
SELECT ...
FROM ...
UNPIVOT (column_to_unpivotFOR new_column_nameIN (list_of_columns))
其中,column_to_unpivot是要進行列轉行的列;new_column_name是新生成的列的名稱;list_of_columns是要轉換為行的列的列表。
實現案例中的結果可以用如下方式:
SELECT *
FROM sales
UNPIVOT (amount FOR year IN ("2018", "2019", "2020"));
方式2.UNION ALL
SELECT product, '2018' AS year, "2018" AS amount FROM sales
UNION ALL
SELECT product, '2019' AS year, "2019" AS amount FROM sales
UNION ALL
SELECT product, '2020' AS year, "2020" AS amount FROM sales;
注意:單引號表示的是固定字符2018即字段名2018,雙引號表示字段2018下的值