Oracle Pivot/Unpivot
此特性只适用于Oracle 11g 以上版本
CREATE TABLE CUSTOMERS
(
CUST_ID NUMBER(10),
CUST_NAME VARCHAR2(20),
STATE_CODE VARCHAR2(2),
TIMES_PURCHASED NUMBER(3)
);
INSERT INTO CUSTOMERS VALUES(1,'ANKER','CT',1);
INSERT INTO CUSTOMERS VALUES(1,'ANKER','ET',2);
INSERT INTO CUSTOMERS VALUES(1,'ANKER','DT',3);
INSERT INTO CUSTOMERS VALUES(1,'ANKER','QD',4);
INSERT INTO CUSTOMERS VALUES(2,'JONH','ET',2);
INSERT INTO CUSTOMERS VALUES(2,'JONH','DT',3);
INSERT INTO CUSTOMERS VALUES(2,'JONH','QD',2);
INSERT INTO CUSTOMERS VALUES(3,'QIANG','DT',3);
INSERT INTO CUSTOMERS VALUES(3,'QIANG','QD',4);
COMMIT;
--该记录显示了客户所在的州以及该客户在商店购物的次数。当该客户从商店购买更多物品时,列 times_purchased 会进行更新。
SQL> SELECT * FROM CUSTOMERS;
CUST_ID CUST_NAME ST TIMES_PURCHASED
---------- -------------------- -- ---------------
1 Anker CT 1
1 Anker ET 2
1 Anker DT 3
1 Anker QD 4
2 Jonh ET 2
2 Jonh DT 3
2 Jonh QD 2
3 Qiang DT 3
3 Qiang QD 4
已选择9行。
PIVOT用法
--1.查看每个州,每个客户的购买频率
SELECT * FROM CUSTOMERS
PIVOT(
SUM(TIMES_PURCHASED) FOR STATE_CODE IN ('QD' AS "New York", 'CT' AS "Connecticut", 'ET' AS "New Jersey", 'DT' AS "Missouri")
);
--从结果可以看出,pivot将针对非pivot涉及的字段进行group by,pivot中的 in (...)子句中的值将作为列,聚合的值将作为列的值
CUST_ID CUST_NAME New York Connecticut New Jersey Missouri
---------- -------------------- ---------- ----------- ---------- ----------
1 Anker 4 1 2 3
2 Jonh 2 2 3
3 Qiang 4 3
--2.了解各个州的购买频率,即,各个州有多少客户只购物一次、两次、三次等等。如果使用常规 SQL
SQL> SELECT STATE_CODE, TIMES_PURCHASED, COUNT(*)
2 FROM CUSTOMERS
3 GROUP BY STATE_CODE, TIMES_PURCHASED;
ST TIMES_PURCHASED COUNT(*)
-- --------------- ----------
QD 4 2
QD 2 1
CT 1 1
ET 2 2
DT 3 3
--这样看起来不太直观
SELECT *
FROM
(
SELECT TIMES_PURCHASED, STATE_CODE FROM CUSTOMERS) T
PIVOT(
COUNT(STATE_CODE) FOR STATE_CODE IN ('QD', 'CT', 'ET', 'DT')
)
TIMES_PURCHASED 'QD' 'CT' 'ET' 'DT'
--------------- ---------- ---------- ---------- ----------
1 0 1 0 0
2 1 0 2 0
4 2 0 0 0
3 0 0 0 3
--但是假设您希望显示州名而非缩写
SELECT *
FROM
(
SELECT TIMES_PURCHASED as "Puchase Frequency", STATE_CODE FROM CUSTOMERS) T
PIVOT(COUNT(STATE_CODE) as CNT
FOR STATE_CODE IN ('QD' AS "New York", 'CT' AS "Connecticut", 'ET' AS "New Jersey", 'DT' AS "Missouri")
);
Puchase Frequency New York_CNT Connecticut_CNT New Jersey_CNT Missouri_CNT
----------------- ------------ --------------- -------------- ------------
1 0 1 0 0
2 1 0 2 0
4 2 0 0 0
3 0 0 0 3
-----------------------------------------------------------------------------------------------------------------------------------
Unpivot 讲解
--1.将上面的pivot后的结果进行反转回来
CREATE TABLE TAB_MATRIX1
AS
SELECT * FROM CUSTOMERS
PIVOT(
SUM(TIMES_PURCHASED) FOR STATE_CODE IN ('QD' AS "NEW YORK", 'CT' AS "CONNECTICUT", 'ET' AS "NEW JERSEY", 'DT' AS "MISSOURI")
);
--查询表
SQL> SELECT * FROM TAB_MATRIX1
2 ;
CUST_ID CUST_NAME New York Connecticut New Jersey Missouri
---------- -------------------- ---------- ----------- ---------- ----------
1 Anker 4 1 2 3
2 Jonh 2 2 3
3 Qiang 4 3
--从结果中可以看出,for .. in (..)中的列名将作为state_code列的值,字段state_counts中的列将由原来的列值来代替
SQL> SELECT * FROM TAB_MATRIX1
2 unpivot
3 (
4 state_counts
5 for state_code in ("New York","Connecticut","New Jersey","Missouri")
6 );
CUST_ID CUST_NAME STATE_CODE STATE_COUNTS
---------- -------------------- ----------- ------------
1 Anker New York 4
1 Anker Connecticut 1
1 Anker New Jersey 2
1 Anker Missouri 3
2 Jonh New York 2
2 Jonh New Jersey 2
2 Jonh Missouri 3
3 Qiang New York 4
3 Qiang Missouri 3
已选择9行。
--将上面第二个结果也进行反转
CREATE TABLE TAB_MATRIX2 AS
SELECT *
FROM
(
SELECT TIMES_PURCHASED as "Puchase Frequency", STATE_CODE FROM CUSTOMERS) T
PIVOT(COUNT(STATE_CODE) as CNT
FOR STATE_CODE IN ('QD' AS "New York", 'CT' AS "Connecticut", 'ET' AS "New Jersey", 'DT' AS "Missouri")
);
SQL> SELECT * FROM TAB_MATRIX2;
Puchase Frequency New York_CNT Connecticut_CNT New Jersey_CNT Missouri_CNT
----------------- ------------ --------------- -------------- ------------
1 0 1 0 0
2 1 0 2 0
4 2 0 0 0
3 0 0 0 3
SELECT * FROM TAB_MATRIX2
UNPIVOT
(
CNT_STATE_CODE
FOR STATE_CODE IN ("New York_CNT","Connecticut_CNT","New Jersey_CNT","Missouri_CNT")
);
Puchase Frequency STATE_CODE CNT_STATE_CODE
----------------- --------------- --------------
1 New York_CNT 0
1 Connecticut_CNT 1
1 New Jersey_CNT 0
1 Missouri_CNT 0
2 New York_CNT 1
2 Connecticut_CNT 0
2 New Jersey_CNT 2
2 Missouri_CNT 0
4 New York_CNT 2
4 Connecticut_CNT 0
4 New Jersey_CNT 0
4 Missouri_CNT 0
3 New York_CNT 0
3 Connecticut_CNT 0
3 New Jersey_CNT 0
3 Missouri_CNT 3
---------------------------------------------------------------------------------------------------------------------
Oracle 11g之前的版本如何实现行转列及列转行
CREATE TABLE T
AS
SELECT * FROM
(
SELECT OWNER,OBJECT_TYPE,COUNT(*) AS CNT FROM DBA_OBJECTS
GROUP BY OWNER,OBJECT_TYPE
) WHERE ROWNUM <= 3;
admin@ORCL> SELECT * FROM T;
OWNER OBJECT_TYPE CNT
------------------------------ ------------------- ----------
BI SYNONYM 8
HR VIEW 1
HR INDEX 19
--列转行
admin@ORCL> SELECT OWNER,
2 SUM(CASE
3 WHEN OBJECT_TYPE = 'SYNONYM' THEN
4 CNT
5 ELSE
6 0
7 END) AS TYPE_SYNONYM,
8 SUM(CASE
9 WHEN OBJECT_TYPE = 'VIEW' THEN
10 CNT
11 ELSE
12 0
13 END) AS TYPE_VIEW,
14 SUM(CASE
15 WHEN OBJECT_TYPE = 'INDEX' THEN
16 CNT
17 ELSE
18 0
19 END) AS TYPE_INDEX
20 FROM T
21 GROUP BY OWNER;
OWNER TYPE_SYNONYM TYPE_VIEW TYPE_INDEX
------------------------------ ------------ ---------- ----------
HR 0 1 19
BI 8 0 0
--列转行
DROP TABLE T PURGE;
CREATE TABLE T
(
OWNER VARCHAR2(10),
TYPE_SYNONYM INT,
TYPE_VIEW INT,
TYPE_INDEX INT
);
INSERT INTO T VALUES('HR','0','1','19');
INSERT INTO T VALUES('BI','8','0','0');
COMMIT;
--查看数据
admin@ORCL> SELECT * FROM T;
OWNER TYPE_SYNONYM TYPE_VIEW TYPE_INDEX
---------- ------------ ---------- ----------
HR 0 1 19
BI 8 0 0
--列转行
admin@ORCL> SELECT OWNER, 'SYNONYM' AS TYPE, TYPE_SYNONYM
2 FROM T
3 UNION ALL
4 SELECT OWNER, 'VIEW', TYPE_VIEW
5 FROM T
6 UNION ALL
7 SELECT OWNER, 'INDEX', TYPE_INDEX FROM T;
OWNER TYPE TYPE_SYNONYM
---------- ------- ------------
HR SYNONYM 0
BI SYNONYM 8
HR VIEW 1
BI VIEW 0
HR INDEX 19
BI INDEX 0
相关推荐
在Oracle数据库中,行转列(也称为数据透视)和列转行(unpivot)是SQL查询中用于数据转换的高级功能。从Oracle 11g版本开始,引入了PIVOT和UNPIVOT关键字,以支持显式的查询转换,即从行数据转换为列数据,或从列...
- T-SQL_经典行专列、列转行,分页及存储过程.doc:T-SQL是SQL Server的扩展,但其中的行转列和分页概念与Oracle相似。在Oracle中,可以使用ROW_NUMBER()函数配合PARTITION BY和ORDER BY来实现分页查询。 - oracle_...
oracle行转列,列转行的例子
Oracle行转列 Oracle行转列是指在Oracle数据库中将行数据转换为列数据或将列数据转换为行数据的操作。这种操作在实际应用中非常有用,例如,在数据报表、数据分析和数据挖掘等领域都需要使用行转列操作。 1. 列...
DB2 SQL 通过函数(CONCAT/POSSTR/LOCATE)实现行转列,列转行 可以按照标点把多列转换为一行,多行转换为一列
列转行(Pivot)和行转列(Unpivot)是两种基本操作,可以将数据按照不同的维度进行组织。传统的列转行方法通常涉及`DECODE`或`CASE`函数与聚合函数如`MAX`或`MIN`的结合,但这些方法可能在处理大量数据时对性能造成...
sql 行转列 与列转行,oracle ,msssql等,详细数据库操作方法,各种例子,欢迎大家学习。、~
Oracle 列转行问题解决方案 Oracle 数据库中,列转行问题是一个非常传统的话题。在这个问题中,我们需要将行数据转换成不同的列表示,或者将不同的列数据写到同一列的不同行上。这种问题在实际应用中非常常见,如将...
oracle中实现列转行实例,有表的创建,数据的插入,查询的sql
DECODE函数在处理列转行的问题时,尤其适用于将多列数据合并到一行中,使得数据展示更加简洁明了。下面我们将详细讲解DECODE函数的使用方法以及如何在列转行操作中应用它。 DECODE函数的基本语法如下: ```sql ...
许多情况下,由于程序中需要将行转为列展示,如果使用ORACLE那么这个资源适合你。
理解日常工作中常用到的多列分组, 如【统计不同部门、 不同职位的平均工资】和 行转列 包含例子 和 个人理解分析
`PIVOT`是Oracle数据库特有的行转列函数,而`CASE`语句则在大多数SQL方言中可用。 3. **执行动态SQL**:使用`EXEC`或`sp_executesql`(在SQL Server中)来执行动态构建的SQL语句。 4. **处理结果**:存储过程可以...
因此用到了逗号分隔列转行的方法。目前该方法只适合在oracle数据库中使用。该方法只需要sql语句就可以实现列转行。 下面给出该方法的示例: select a,b,c from(with test as (select ‘aaa’ a,’bbb’ b,’1,2,3...
在Oracle Developer中,"列转行小工具"是一种实用功能,它主要用于处理数据库表中的数据,将多列数据转换为单列数据,通常涉及到的是数据的行列转换操作。这种操作在处理复杂的数据分析、报表生成或者接口对接时非常...
SELECT TRIM(',' FROM SYS.STRAGG(A_NAME||NVL2(A_NAME,',','')))as nams FROM A_TEMP
在Oracle数据库管理中,行转列与列转行是常见的数据操作需求,特别是在数据分析和报表展示时。这两种操作可以通过不同的SQL技巧实现,如使用CASE语句、PIVOT和UNPIVOT操作,以及DECODE函数等。下面将详细介绍如何在...