pivot & unpivot(行列转换)

一、pivot
The data returned by business intelligence queries is often most usable if presented in a crosstabular format.

The pivot_clause of the SELECT statement lets you write crosstabulation queries that rotate rows into columns, aggregating data in the process of the rotation.
select语句中使用转置子句,可以完成交叉表的查询:行转列,聚合数据
Pivoting is a key technique in data warehouses. In it, you transform multiple rows of input into fewer and generally wider rows in the data warehouse.
转置是数据仓库中的关键技术。在数据仓库中,使用转置,可以将多行数据转为较少的数据行输出
When pivoting, an aggregation operator is applied for each item in the pivot column value list.
使用转置技术时,每个item都要有聚合操作
The pivot column cannot contain an arbitrary expression. If you need to pivot on an expression, then you should alias the expression in a view before the PIVOT operation.
转置列不能包含表达式。如果你想要转置表达式,应该在转置操作前,给表达式别名。

二、基本语法
The basic syntax is as follows:
基本语法:
SELECT ....
FROM <table-expr>
   PIVOT
     (
      aggregate-function(<column>)
      FOR <pivot-column> IN (<value1>, <value2>,..., <valuen>)
        ) AS <alias>
WHERE .....

三、示例:
1、单列转置(行转列)
To illustrate the use of pivoting, create the following view as a basis for later examples:
CREATE VIEW sales_view AS
SELECT
 prod_name product, country_name country, channel_id channel,
 SUBSTR(calendar_quarter_desc, 6,2) quarter,
 SUM(amount_sold) amount_sold, SUM(quantity_sold) quantity_sold
FROM sales, times, customers, countries, products
WHERE sales.time_id = times.time_id AND
  sales.prod_id = products.prod_id AND
  sales.cust_id = customers.cust_id AND
  customers.country_id = countries.country_id
GROUP BY prod_name, country_name, channel_id,
 SUBSTR(calendar_quarter_desc, 6, 2);
 
--
The following statement illustrates a typical  pivot on the channel column:
1)分组字段为product
SELECT * FROM
  (SELECT product, channel, amount_sold
   FROM sales_view
   ) S PIVOT (SUM(amount_sold)
   FOR CHANNEL IN (3 AS DIRECT_SALES, 4 AS INTERNET_SALES,
                   5 AS CATALOG_SALES, 9 AS TELESALES))
ORDER BY product;


2)分组字段为country


3)分组字段,product,country
...
Note that the output has created four new aliased columns, DIRECT_SALES, INTERNET_SALES, CATALOG_SALES, and TELESALES, one for each of the pivot values. The output is a sum.
If no alias is provided, the column heading will be the values of the IN-list.
输出结果中,新产生了4个别名列,DIRECT_SALES, INTERNET_SALES, CATALOG_SALES, and TELESALES,对应不同的转置列的值。如果没有别名的话,列标题就是 in list中的pivot column value


2、多字段转置Pivoting on Multiple Columns
多列转置
You can pivot on more than one column. The following statement illustrates a typical multiple column pivot:
--用于和下面的sql比较输出结果:
select PRODUCT,CHANNEL,QUARTER,SUM(quantity_sold) from SALES_VIEW
group by PRODUCT,CHANNEL,quarter
order by PRODUCT;


SELECT *
FROM
     (SELECT product, channel, quarter, quantity_sold
      FROM sales_view
     ) PIVOT (SUM(quantity_sold)
                FOR (channel, quarter) IN
                  ((5, '02') AS CATALOG_Q2,
                   (4, '01') AS INTERNET_Q1,
                   (4, '04') AS INTERNET_Q4,
                   (2, '02') AS PARTNERS_Q2,
                   (9, '03') AS TELE_Q3
                  )
                );
上面的sql:product是隐含的分组字段, channel,和quarter是pivoting columns,quantity_sold是聚合字段(sum)。
输出结果为6列:
product列
SUM(quantity_sold) as CATALOG_Q2,
INTERNET_Q1
INTERNET_Q4
PARTNERS_Q2
TELE_Q3 


3、Pivoting: Multiple Aggregates,多个聚合函数

You can pivot with multiple aggregates, as shown in the following example:

SELECT *

FROM

     (SELECT product, channel, amount_sold, quantity_sold

      FROM sales_view

     ) PIVOT (SUM(amount_sold) AS sums,

              SUM(quantity_sold) AS sumq

              FOR channel IN (5, 4, 2, 9)

               )

ORDER BY product;


Note that the query creates column headings by concatenating the pivot values (or alias) with the alias of the aggregate function, plus an underscore

输出结果的标题:pivot values连接上aggregate function


4、Distinguishing PIVOT-Generated Nulls from Nulls in Source Data

create table SALE2

(

PROD_ID int,

QTR varchar2(5),

AMOUNT_SOLD int

)


insert into SALE2 values(100,'Q1',10);

insert into SALE2 values(100,'Q1',20);

insert into SALE2 values(100,'Q2',null);

insert into SALE2 values(200,'Q1',50);

You can distinguish between null values that are generated from the use of PIVOT and those that exist in the source data. The following example illustrates nulls that PIVOT generates.

The following query returns rows with 5 columns, column prod_id, and pivot resulting columns Q1Q1_COUNT_TOTALQ2Q2_COUNT_TOTAL. For each unique value of prod_id,Q1_COUNT_TOTAL returns the total number of rows whose qtr value is Q1, that is, and Q2_COUNT_TOTAL returns the total number of rows whose qtr value is Q2.

Assume we have a table sales2 of the following structure:

PROD_ID   QTR  AMOUNT_SOLD
-------   ---  -----------
100        Q1           10
100        Q1           20
100        Q2         NULL
200        Q1           50

SELECT *
FROM sales2
        PIVOT
         ( SUM(amount_sold), COUNT(*) AS count_total
           FOR qtr IN ('Q1', 'Q2')
         );

PROD_ID    "Q1"   "Q1_COUNT_TOTAL"  "Q2"       "Q2_COUNT_TOTAL"
-------    ----   ----------------  ---------  ----------------
    100      20                  2   NULL <1>                 1
    200      50                  1   NULL <2>                 0

From the result, we know that for prod_id 100, there are 2 sales rows for quarter Q1, and 1 sales row for quarter Q2; for prod_id 200, there is 1 sales row for quarter Q1, and no sales row for quarter Q2.So, in Q2_COUNT_TOTAL, you can identify that NULL<1> comes from a row in the original table whose measure is of null value, while NULL<2> is due to no row being present in the original table for prod_id 200 in quarter Q2.


四、Unpivoting Operations

An unpivot does not reverse a PIVOT operation. Instead, it rotates data from columns into rows. If you are working with pivoted data, an UNPIVOT operation cannot reverse any aggregations that have been made by PIVOT or any other means. 实现列转行

1、创建pivoted data

To illustrate unpivoting, first create a pivoted table that includes four columns, for quarters of the year:

CREATE TABLE pivotedTable AS

SELECT *

FROM (SELECT product, quarter, quantity_sold, amount_sold

      FROM sales_view)

    PIVOT

    (

       SUM(quantity_sold) AS sumq, SUM(amount_sold) AS suma

       FOR quarter IN ('01' AS Q1, '02' AS Q2, '03' AS Q3, '04' AS Q4));

pivotedTable 输出如下:(共71行)


The following  UNPIVOT  operation rotates the quarter columns into rows. For each product, there will be four rows, one for each quarter.
SELECT product, DECODE(quarter, 'Q1_SUMQ', 'Q1', 'Q2_SUMQ', 'Q2', 'Q3_SUMQ', 'Q3',  --decode 函数只是用来改变输出结果的列标题
   'Q4_SUMQ', 'Q4') AS quarter, quantity_sold
FROM pivotedTable
   UNPIVOT INCLUDE NULLS
       (quantity_sold
        FOR quarter IN (Q1_SUMQ, Q2_SUMQ, Q3_SUMQ, Q4_SUMQ))
ORDER BY product, quarter;

--上面的语句与下面的sql等价:
select PRODUCT, QUARTER1,
        --DECODE(QUARTER1, 'Q1_SUMQ', 'Q1', 'Q2_SUMQ', 'Q2', 'Q3_SUMQ', 'Q3', 'Q4_SUMQ', 'Q4') AS QUARTER1,
         quantity_sold1
from PIVOTEDTABLE
   UNPIVOT INCLUDE nulls
       (QUANTITY_SOLD1
        for QUARTER1 in ( Q1_SUMQ as 'Q1', Q2_SUMQ as 'Q2', Q3_SUMQ as 'Q3', Q4_SUMQ as 'Q4' ))  --改变输出结果的列标题
order by PRODUCT, QUARTER1;

输出结果集是 pivotedTable  的4倍。(原来 pivotedTable  表的一行数据转置为4行数据


2、比较include nulls和exclude nulls

Note the use of INCLUDE NULLS in this example. You can also use EXCLUDE NULLS, which is the default setting.




3、unpivot using two columns
SELECT product, quarter, quantity_sold, amount_sold
FROM pivotedTable
   UNPIVOT INCLUDE NULLS
       (
        (quantity_sold, amount_sold)
        FOR quarter IN ((Q1_SUMQ, Q1_SUMA) AS 'Q1', (Q2_SUMQ, Q2_SUMA) AS 'Q2', (Q3_SUMQ, Q3_SUMA) AS 'Q3', (Q4_SUMQ, Q4_SUMA) AS 'Q4'))
ORDER BY product, quarter;
等价sql 1:
SELECT product, quarter2, quantity_sold2, amount_sold2
FROM pivotedTable
   UNPIVOT INCLUDE NULLS
       (
        (QUANTITY_SOLD2, AMOUNT_SOLD2)
        for QUARTER2 in ((Q1_SUMQ, Q1_SUMA) as 'Q1', (Q2_SUMQ, Q2_SUMA) as 'Q2', (Q3_SUMQ, Q3_SUMA) as 'Q3', (Q4_SUMQ, Q4_SUMA) as 'Q4'))
ORDER BY product, quarter2;

输出结果:

五、Wildcard and Subquery Pivoting with XML Operations
if you want to use a wildcard argument or subquery in your pivoting columns, you can do so with PIVOT XML syntax. With PIVOT XML, the output of the operation is properly formatted XML.
The following example illustrates using the wildcard keyword,  ANY . It outputs XML that includes all channel values in  sales_view :

Note that the keyword ANY is available in PIVOT operations only as part of an XML operation. This output includes data for cases where the channel exists in the data set. Also note that aggregation functions must specify a GROUP BY clause to return multiple values, yet the pivot_clause does not contain an explicit GROUP BY clause. Instead, the pivot_clause performs an implicit GROUPBY.  

隐式group by,不用强制加group by


The following example illustrates using a subquery. It outputs XML that includes all channel values and the sales data corresponding to each channel:

SELECT *
FROM
     (SELECT product, channel, quantity_sold
      FROM sales_view
     ) PIVOT XML(SUM(quantity_sold)
                for CHANNEL in (select distinct CHANNEL_ID from CHANNELS)
             );




 
 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/28194062/viewspace-1755575/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/28194062/viewspace-1755575/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值