`

Oracle 行转列,列转行

阅读更多
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行转列之pivot

    在Oracle数据库中,行转列(也称为数据透视)和列转行(unpivot)是SQL查询中用于数据转换的高级功能。从Oracle 11g版本开始,引入了PIVOT和UNPIVOT关键字,以支持显式的查询转换,即从行数据转换为列数据,或从列...

    oracle行转列

    - T-SQL_经典行专列、列转行,分页及存储过程.doc:T-SQL是SQL Server的扩展,但其中的行转列和分页概念与Oracle相似。在Oracle中,可以使用ROW_NUMBER()函数配合PARTITION BY和ORDER BY来实现分页查询。 - oracle_...

    oracle行转列,列转行的例子

    oracle行转列,列转行的例子

    Oracle行转列

    Oracle行转列 Oracle行转列是指在Oracle数据库中将行数据转换为列数据或将列数据转换为行数据的操作。这种操作在实际应用中非常有用,例如,在数据报表、数据分析和数据挖掘等领域都需要使用行转列操作。 1. 列...

    DB2 SQL 实现行转列,列转行

    DB2 SQL 通过函数(CONCAT/POSSTR/LOCATE)实现行转列,列转行 可以按照标点把多列转换为一行,多行转换为一列

    Oracle的列转行问题

    列转行(Pivot)和行转列(Unpivot)是两种基本操作,可以将数据按照不同的维度进行组织。传统的列转行方法通常涉及`DECODE`或`CASE`函数与聚合函数如`MAX`或`MIN`的结合,但这些方法可能在处理大量数据时对性能造成...

    sql行转列,与列转行

    sql 行转列 与列转行,oracle ,msssql等,详细数据库操作方法,各种例子,欢迎大家学习。、~

    oracle的列转行问题

    Oracle 列转行问题解决方案 Oracle 数据库中,列转行问题是一个非常传统的话题。在这个问题中,我们需要将行数据转换成不同的列表示,或者将不同的列数据写到同一列的不同行上。这种问题在实际应用中非常常见,如将...

    oracle中实现列转行实例

    oracle中实现列转行实例,有表的创建,数据的插入,查询的sql

    ORACLE 列转行 DECODE函数用法

    DECODE函数在处理列转行的问题时,尤其适用于将多列数据合并到一行中,使得数据展示更加简洁明了。下面我们将详细讲解DECODE函数的使用方法以及如何在列转行操作中应用它。 DECODE函数的基本语法如下: ```sql ...

    ORACLE行转列

    许多情况下,由于程序中需要将行转为列展示,如果使用ORACLE那么这个资源适合你。

    oracle 多列分组和行转列 理解和实例

    理解日常工作中常用到的多列分组, 如【统计不同部门、 不同职位的平均工资】和 行转列 包含例子 和 个人理解分析

    sql动态行转列 存储过程

    `PIVOT`是Oracle数据库特有的行转列函数,而`CASE`语句则在大多数SQL方言中可用。 3. **执行动态SQL**:使用`EXEC`或`sp_executesql`(在SQL Server中)来执行动态构建的SQL语句。 4. **处理结果**:存储过程可以...

    Oracle逗号分隔列转行实现方法

    因此用到了逗号分隔列转行的方法。目前该方法只适合在oracle数据库中使用。该方法只需要sql语句就可以实现列转行。  下面给出该方法的示例: select a,b,c from(with test as (select ‘aaa’ a,’bbb’ b,’1,2,3...

    列转行小工具

    在Oracle Developer中,"列转行小工具"是一种实用功能,它主要用于处理数据库表中的数据,将多列数据转换为单列数据,通常涉及到的是数据的行列转换操作。这种操作在处理复杂的数据分析、报表生成或者接口对接时非常...

    oracle的列转行函数

    SELECT TRIM(',' FROM SYS.STRAGG(A_NAME||NVL2(A_NAME,',','')))as nams FROM A_TEMP

    Oracle的数据表中行转列与列转行的操作实例讲解

    在Oracle数据库管理中,行转列与列转行是常见的数据操作需求,特别是在数据分析和报表展示时。这两种操作可以通过不同的SQL技巧实现,如使用CASE语句、PIVOT和UNPIVOT操作,以及DECODE函数等。下面将详细介绍如何在...

Global site tag (gtag.js) - Google Analytics