Oracle 行列转换(PIVOT)的N种方法

Oracle SQL - pivoting one row of several columns into one column of several rows

Oracle Tips by Burleson Consulting

There are many ways to use Oracle to pivot column data for display on a single row:

0 - Download SQL into Excel spreadsheet pivot table

Excel spreadsheets are a great way to pivot and analyze Oracle data, and tools like Excel-DB provide a fast API for downloading Oracle data into spreadsheets. Using excel pivot tables with Oracle data is a fast, easy way to use Oracle business intelligence without buying expensive OLAP solutions (Hyperion, Oracle BI Suite).  Here is an example.

1 - Write a PL/SQL function

You can write a PL/SQL function to display multiple rows values on a single line.  Martin Chadderton has written a Pl/SQL function called "stragg" that you can define to display multiple SQL rows on one single line. 

2 - Use the SYS_CONNECT_BY_PATH operator

This article by Younes Naguib describes how to display multiple values from a single column in a single output row.  In his example, he displays multiple values of the last name column on a single row.  Note his use of the sys_connect_by_path and over operators:

select
   deptno,
   substr(SYS_CONNECT_BY_PATH(lname, ','),2) name_list
from
   (
   select
     lname,
     deptno,
     count(*) OVER ( partition by deptno ) cnt,
     ROW_NUMBER () OVER ( partition by deptno order by lname) seq
   from
     igribun.emp
   where
     deptno is not null)
where
   seq=cnt
start with
   seq=1
connect by prior
   seq+1=seq
and prior
   deptno=deptno;
DEPTNO NAME_LIST
1      Komers,Mokrel,Stenko
2      Hung,Tong
3      Hamer
4      Mansur

3 - Cross join

Matt contributed this handy SQL techniques to pivot one row of several columns into a single column with several row, using the Oracle cross join syntax.  Matt notes that the Cross join "has other uses in conjunction with a WHERE clause to create triangular result sets for rolling totals etc (though thanks to analytic functions those things are very nice and easy)".

SELECT
  ite,
  case
    when ite = 'item1' then item1
    when ite = 'item2' then item2
    when ite = 'item3' then item3
  end as val
FROM
(
  SELECT
    pivoter.ite,
    item1,
    item2,
    item3
  FROM
    someTable
    CROSS JOIN
    (
      select 'item1' as ite from dual
      UNION ALL
      select 'item2' as ite from dual
      UNION ALL
      select 'item3' as ite from dual
    )pivoter
)

4 - Oracle analytic Lag-Over Function

Analytic functions have a pronounced performance improvement since they avoid an expensive self-join and only make one full-table scan to get the results.  This site shows an example of using the Oracle LAG function to display multiple rows on a single column:

Matt contributed this handy SQL techniques to pivot one row of several columns into a single column with several row, using the Oracle cross join syntax.  Matt notes that the Cross join "has other uses in conjunction with a WHERE clause to create triangular result sets for rolling totals etc (though thanks to analytic functions those things are very nice and easy)".

Also see how to display Oracle SQL output rows on one single line.

SELECT
  ite,
  case
    when ite = 'item1' then item1
    when ite = 'item2' then item2
    when ite = 'item3' then item3
  end as val
FROM
(
  SELECT
    pivoter.ite,
    item1,
    item2,
    item3
  FROM
    someTable
    CROSS JOIN
    (
      select 'item1' as ite from dual
      UNION ALL
      select 'item2' as ite from dual
      UNION ALL
      select 'item3' as ite from dual
    )pivoter

 

附录:

Display Oracle SQL output rows on one single line

Oracle Tips by Burleson Consulting

Question:  How to I get my SQL output rows to display on one line? select ename from emp;
Smith Jones Baker
I want the SQL output on one line, like this: select ename from emp;
Smith, Jones, Baker How do I get multiple rows onto one line of output?
Answer: I have complete notes and samples of displaying multiple columns on a single row. You can also use the undocumented SQL wm_concat function. You can displaying multiple columns per row with sys_connect_by_path, or you can write a PL/SQL function to display multiple rows values on a single line. 
Also look at using Oracle analytics (the LAG and OVER functions) to display data in a single row of output.
Martin Chadderton has written a Pl/SQL function called "stragg" that you can define to display multiple SQL rows on one single line.  Once defined, you embed the function within your SQL to display your output on a single line:

select stragg(ename) from emp;
Smith, Jones, Baker
Sorting SQL output on a single line

Note that sorting is tricky, and even though the output displays on a single line, the "order by" does not sort the rows on the one line:

select stragg(ename) from emp order by ename;
Smith, Jones, Baker
The in-line view ensures that the SQL output appears sorted on one line of output:
select stragg(ename)
from
   (select stragg(ename) from emp order by ename);
Baker, Jones, Smith
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Oracle数据库中,行列转换是指将行数据转换为列数据或将列数据转换为行数据的操作。实现行列转换的最简单方法是使用OraclePIVOT和UNPIVOT关键字。 1. 行转列(PIVOT): 使用PIVOT关键字可以将行数据转换为列数据。 例如,有如下的表格:Student | ID | Name | Subject | Score | |----|--------|----------|-------| | 1 | John | English | 80 | | 1 | John | Math | 90 | | 2 | Maggie | English | 85 | | 2 | Maggie | Math | 95 | 我们想要将Subject列转换为列标题,即将"English"和"Math"作为列名。可以使用以下SQL语句进行转换: ``` SELECT * FROM ( SELECT ID, Name, Subject, Score FROM Student ) PIVOT ( MAX(Score) FOR Subject IN ('English', 'Math') ) ``` 运行上述SQL语句后,将会得到以下结果: | ID | Name | English | Math | |----|--------|---------|------| | 1 | John | 80 | 90 | | 2 | Maggie | 85 | 95 | 2. 列转行(UNPIVOT): 使用UNPIVOT关键字可以将列数据转换为行数据。 例如,有如下的表格:Subject | ID | English | Math | |----|---------|------| | 1 | 80 | 90 | | 2 | 85 | 95 | 我们想要将英语分数(English)和数学分数(Math)转换为行数据。可以使用以下SQL语句进行转换: ``` SELECT * FROM ( SELECT ID, English, Math FROM Subject ) UNPIVOT ( Score FOR Subject IN (English, Math) ) ``` 运行上述SQL语句后,将会得到以下结果: | ID | Subject | Score | |----|---------|-------| | 1 | English | 80 | | 1 | Math | 90 | | 2 | English | 85 | | 2 | Math | 95 | 通过使用PIVOT和UNPIVOT关键字,我们可以轻松地实现Oracle数据库中行列转换的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值