oracle中行转列函数是什么

什么是行转列函数

行转列函数是指将一列数据转换为一行数据的函数,或者将一行数据转换为一列数据的函数。在Oracle数据库中,行转列函数有多种实现方式,例如使用PIVOT或UNPIVOT命令、使用CASE语句、使用XML函数等。

其中,PIVOT和UNPIVOT命令的使用较为简单,但是只能实现单个字段的转换,而使用CASE语句和XML函数可以实现多个字段的转换。

使用PIVOT实现行转列

PIVOT语法

PIVOT语法如下:

SELECT * 

FROM (

SELECT column1, column2, column3

FROM table_name

)

PIVOT (

aggregate_function(column1)

FOR column2 IN (value1, value2, ... value_n)

);

其中,column1为需要转换的列,column2为用于构建新表头的列,aggregate_function为指定对新表头所对应的数据进行计算的聚合函数(如SUM、AVG等),value1、value2、...value_n为构建新表头的值。

使用PIVOT实现单个字段的行转列

假设我们有以下一张表:

关键词 排名 日期
oracle 1 2022-01-01
oracle 2 2022-01-02
oracle 1 2022-01-03
java 2 2022-01-01
java 1 2022-01-02
java 2 2022-01-03

现在我们需要将该表中的日期列转换为新的表头,示例代码如下:

SELECT *

FROM (

SELECT keyword, rank, to_char(date,'yyyy-mm-dd') as date

FROM table_name

)

PIVOT (

max(rank)

FOR date IN ('2022-01-01', '2022-01-02', '2022-01-03')

);

执行以上代码,将得到以下结果:

关键词 2022-01-01 2022-01-02 2022-01-03
oracle 1 2 1
java 2 1 2

可以看到,新的表头为日期列的值,表中的数据则为原表中对应日期下的rank值,且使用了max聚合函数取值。

使用PIVOT实现多个字段的行转列

如果需要将多个字段行转列,PIVOT命令的语法并不能满足需求,此时需要使用带有CASE语句的PIVOT语句来实现。

同样以上述表格为例,假设我们需要同时将keyword和rank两个字段的值行转列,示例代码如下:

SELECT *

FROM (

SELECT keyword, rank, to_char(date,'yyyy-mm-dd') as date

FROM table_name

)

PIVOT (

max(rank) as rank, max(keyword) as keyword

FOR date IN ('2022-01-01', '2022-01-02', '2022-01-03')

);

执行以上代码,将得到以下结果:

2022-01-01_KEYWORD 2022-01-01_RANK 2022-01-02_KEYWORD 2022-01-02_RANK 2022-01-03_KEYWORD 2022-01-03_RANK
1 oracle 1 oracle 2 oracle 1
2 java 2 java 1 java 2

可以看到,结果表中共有6列(3个日期值,每个日期值对应一个keyword和rank值),每列的名称都由date列和聚合函数和需要转换的列组合而成。

使用UNPIVOT实现列转行

UNPIVOT语法

UNPIVOT语法如下:

SELECT *

FROM (

SELECT column1, column2, column3, ...

FROM table_name

)

UNPIVOT (

value_column

FOR unpivot_column IN (column2, column3, ...)

);

其中,value_column为需要转换为行的值所在的列,unpivot_column为需要转换为行的列。

使用UNPIVOT实现行转列

假设我们有以下一张表:

ID 2022-01-01 2022-01-02 2022-01-03
1 10 20 30
2 25 35 45
3 15 30 45

现在我们需要将该表中的2022-01-01、2022-01-02、2022-01-03三列转换为新的行,示例代码如下:

SELECT id, date, value

FROM (

SELECT *

FROM table_name

)

UNPIVOT (

value FOR date IN ("2022-01-01", "2022-01-02", "2022-01-03")

);

执行以上代码,将得到以下结果:

ID DATE VALUE
1 2022-01-01 10
1 2022-01-02 20
1 2022-01-03 30
2 2022-01-01 25
2 2022-01-02 35
2 2022-01-03 45
3 2022-01-01 15
3 2022-01-02 30
3 2022-01-03 45

可以看到,新的结果表中共有3列(id列、date列、value列),其中date列的值为原表中的2022-01-01、2022-01-02、2022-01-03三列。

使用CASE语句实现行转列

CASE语句的语法及使用

CASE语句是一种流程控制语句,使用它可以在SELECT语句中根据条件动态地生成数据。

CASE语句的基本语法如下:

CASE

WHEN condition1 THEN result1

WHEN condition2 THEN result2

...

WHEN conditionn THEN resultn

ELSE result

END

其含义为:当条件condition1成立时,返回结果result1;当条件condition2成立时,返回结果result2;......;当条件conditionn成立时,返回结果resultn;否则返回result。

使用CASE语句实现行转列

使用CASE语句实现行转列,需将需要转换为列的值作为条件进行判断,并配合SUM、MAX等聚合函数将同一种情况下的数据进行汇总。

假设我们有以下一张表:

ID NAME YEAR SALES
1 A 2020 1000
1 A 2021 2000
2 B 2020 3000
2 B 2021 4000

现在我们需要将该表中的YEAR列的数据转换为新的列,示例代码如下:

SELECT NAME, 

SUM(CASE WHEN YEAR=2020 THEN SALES ELSE 0 END) as "2020",

SUM(CASE WHEN YEAR=2021 THEN SALES ELSE 0 END) as "2021"

FROM table_name

GROUP BY NAME;

执行以上代码,将得到以下结果:

NAME 2020 2021
A 1000 2000
B 3000 4000

可以看到,新的结果表中共有3列(NAME列、YEAR="2020"的SALES列和YEAR="2021"的SALES列),且每列中的数据为根据条件进行计算而来的汇总数据。

使用XML函数实现行转列

XML函数的语法及使用

Oracle数据库中可以使用XML函数将数据转换为XML格式,并使用XQUERY或XMLTABLE语句解析XML格式的数据。

XML函数的基本语法如下:

SELECT XMLAGG(

XMLELEMENT(

NAME COLUMN, column_name

)

)

FROM table_name;

其中,COLUMN为虚拟的XML元素名称,column_name为表中需要转换的列名。

使用XML函数实现行转列

使用XML函数实现行转列,需将需要转换的数据通过XML函数转换为XML格式,再使用XQUERY或XMLTABLE语句解析XML格式的数据,将XML元素作为新的列。

假设我们有以下一张表:

ID NAME 2020 2021
1 A 1000 2000
2 B 3000 4000

现在我们需要将该表中的2020、2021两列数据转换为新的列,示例代码如下:

SELECT *

FROM (

SELECT name, XMLAGG(

XMLELEMENT(

NAME COLUMN, sales,"_",year

)

).EXTRACT('//text()').getclobval() as sales

FROM (

SELECT name, year, sales

FROM table_name

)

)

XMLTABLE ('for $t in /ROW/COLUMN return $t'

PASSING XMLTYPE(''||sales||''));

执行以上代码,将得到以下结果:

NAME 2020_SALES 2021_SALES
A 1000 2000
B 3000 4000

可以看到,新的结果表中共有3列(NAME列、2020_SALES列、2021_SALES列),且每列中的数据即为原表中对应数据拼接而成的字符串。

总结

行转列函数可以将一行数据转

数据库标签