如何在Oracle中创建透视图

时间:2015-03-12 11:04:24

标签: sql oracle pivot

如何将以下查询转换为数据透视表格式?我需要发送日期作为行跟踪id作为值和shp,sxm作为列,我只是在查询结束时添加格式,如果有人可以让我知道如何将所有这些转换为数据格式,我真的很新所以如果有人可以将我的查询转换为数据透视而不是任何引用,我会很高兴。

3 个答案:

答案 0 :(得分:1)

你需要这样的东西:

with a as (
  select ship_date, 
      case -- <- modify this part
        when tracking_id like 'Q%' then 'Q' 
        else 'N' end 
      category,  
      seen_at_SP1_sort_scan shp1, 
      seen_at_sm1_sort_scan sxm1, 
      seen_at_ds_scan sds1
    from test  -- <- your inner query goes here
  )
select ship_date,
    count(decode(category, 'Q', shp1)) shp1_a,
    count(decode(category, 'N', shp1)) shp1_n,
    count(decode(category, 'Q', sxm1)) sxm1_a,
    count(decode(category, 'N', sxm1)) sxm1_n,
    count(decode(category, 'Q', sds1)) sds1_a,
    count(decode(category, 'N', sds1)) sds1_n,
    count(decode(category, 'Q', 1)) total_a,
    count(decode(category, 'N', 1)) total_n
  from a group by ship_date order by ship_date

结果:

SHIP_DATE   SHP1_A SHP1_N SXM1_A SXM1_N SDS1_A SDS1_N TOTAL_A TOTAL_N
----------- ------ ------ ------ ------ ------ ------ ------- -------
2015-03-09       1      0      2      0      0      0       3       0
2015-03-10       2      2      2      4      0      1       3       4
2015-03-11       0      0      1      0      1      0       1       0
2015-03-12       2      0      0      0      0      0       2       0

而不是test放置您的内部查询,而不是SELECT o.carrier_ref_number...。 根据您的需要修改category的部分,这里不清楚您想要什么。 如果您的标准更复杂,请使用case when...代替decode(category...

如果您使用的是Oracle 11g或更新版本,则可以试用pivot


编辑已修改的完整查询,适用于Oracle 11(透视)和先前版本。 请使用参数{RUN_DATE_YYYYMMDD}替换底部附近的“20150312”,如查询中所示。

对于Oracle 11:

select ship_date, a_shp1 shp1_a, n_shp1 shp1_n, a_sxm1 sxm1_a, n_sxm1 sxm1_n,
    a_shp1+a_sxm1 total_a, n_shp1+n_sxm1 total_n 
  from (
    with ships as (
      select ship_date, category, shp1, sxm1
        from (
          SELECT o.carrier_ref_number tracking_id, o.pkg_manifest_run_date ship_date,
              CASE WHEN (o.carrier_ref_number) LIKE 'Q%' 
                THEN 'A' -- AMZL
                ELSE 'N' -- Non-AMZL
              END Category,
              (SELECT min(transport_shipment_status_date) 
                FROM transport_shipments ts 
                  JOIN transport_shipment_statuses tss 
                    ON tss.transport_shipment_id=ts.transport_shipment_id 
                WHERE ts.carrier_ref_number=o.carrier_ref_number 
                  AND tss.ship_status='X4' AND tss.status_node_id='SHP1'
              ) shp1,   --seen_at_SHP1_sort_scan,
              (SELECT min(transport_shipment_status_date) 
                FROM transport_shipments ts 
                  JOIN transport_shipment_statuses tss 
                    ON tss.transport_shipment_id=ts.transport_shipment_id 
                WHERE ts.carrier_ref_number=o.carrier_ref_number 
                  AND tss.ship_status='X4' AND tss.status_node_id='SXM1'
              ) sxm1   -- seen_at_SXM1_sort_scan
            FROM otm_ob_cust_pkg_records o 
            WHERE o.pkg_manifest_run_date 
              BETWEEN to_date('20150312', 'YYYYMMDD') - 10 
                  AND to_date('20150312', 'YYYYMMDD')
          ) A 
        where shp1 is not null or sxm1 is not null)
    select * from ships
      pivot (count(shp1) as shp1, count(sxm1) as sxm1
        for (category) IN ('A' AS a, 'N' AS n))
  ) order by ship_date

对于较旧的Oracle版本:

select ship_date, 
    sum(decode(category, 'A', shp1)) shp1_a,
    sum(decode(category, 'N', shp1)) shp1_n,
    sum(decode(category, 'A', sxm1)) sxm1_a, 
    sum(decode(category, 'N', sxm1)) sxm1_n,
    sum(decode(category, 'A', shp1)) + sum(decode(category, 'A', sxm1)) total_a,
    sum(decode(category, 'N', shp1)) + sum(decode(category, 'N', sxm1)) total_n
  from (
    SELECT A.ship_date,
      CASE WHEN (A.tracking_id) LIKE 'Q%' THEN 'A' ELSE 'N' END Category,
      COUNT(seen_at_SHP1_sort_scan) shp1, COUNT(seen_at_SXM1_sort_scan) sxm1
    from (
      select o.carrier_ref_number tracking_id, o.pkg_manifest_run_date ship_date,      
          (SELECT min(transport_shipment_status_date) FROM transport_shipments ts JOIN transport_shipment_statuses tss ON tss.transport_shipment_id=ts.transport_shipment_id WHERE ts.carrier_ref_number=o.carrier_ref_number AND tss.ship_status='X4' AND tss.status_node_id='SHP1') seen_at_SHP1_sort_scan,
          (SELECT min(transport_shipment_status_date) FROM transport_shipments ts JOIN transport_shipment_statuses tss ON tss.transport_shipment_id=ts.transport_shipment_id WHERE ts.carrier_ref_number=o.carrier_ref_number AND tss.ship_status='X4' AND tss.status_node_id='SXM1') seen_at_SXM1_sort_scan
        FROM otm_ob_cust_pkg_records o 
        WHERE o.pkg_manifest_run_date BETWEEN to_date('20150312', 'YYYYMMDD') - 10 AND to_date('20150312', 'YYYYMMDD')
      ) A 
    WHERE A.seen_at_SHP1_sort_scan IS NOT NULL OR A.seen_at_SXM1_sort_scan IS NOT NULL 
    GROUP BY A.ship_date, a.tracking_id)
  group by ship_date order by ship_date

您可能希望使用nvl(..., 0)对列进行求和,例如:nvl(sum(decode(category, 'A', shp1)), 0) shp1_a

两个查询的测试结果:

  SHIP_DATE   SHP1_A    SHP1_N   SXM1_A   SXM1_N   TOTAL_A  TOTAL_N
  ----------  -------   -------  -------  -------  -------  -------
  2015-03-11        0         1        0        1        0        2
  2015-03-12        1         0        1        0        2        0

答案 1 :(得分:1)

考虑使用SQL PIVOT函数

http://www.oracle.com/technetwork/articles/sql/11g-pivot-097235.html

示例(来自参考页面):

select * from (
   select times_purchased as "Puchase Frequency", state_code
   from customers t
)
pivot 
(
   count(state_code)
   for state_code in ('NY' as "New York",'CT' "Connecticut",'NJ' "New Jersey",'FL' "Florida",'MO' as "Missouri")
)

答案 2 :(得分:0)

首先,您似乎错过了最终结束“)别名”以完成FROM子句。你有......

FROM ( select statement... ending with 
          columnQuery seen_at_SM1_sort_scan...

需要

FROM ( select statement... ending with 
          columnQuery seen_at_SM1_sort_scan... ) SQLResult

接下来,您没有Group By是一个数据透视图的基础,可以显示每个特定元素的聚合...最多,您需要

GROUP BY
    A.ship_date
   ,CASE A.tracking_id
       WHEN FIRST(A.tracking_id) = Q
           THEN AM
           ELSE Non - AM
           END

最后,显示一些你最终希望获得的样本数据可能会有所帮助,即使它是假数据......并且不要在示例输出中使用TAB进行格式化,因为标签并不总是格式化。 / p>