没有union pivot select的查询

时间:2016-03-07 05:05:00

标签: sql oracle10g

你好,我有如下查询 这个执行时间很长。 请介绍我尝试不同的解决方案 .there是我的查询(oracle 10g)

SELECT *
  FROM (WITH T AS (SELECT COR_ID, COR_COD, WEI1, DAYS, 'WEI1' WEI_TYPE
                     FROM (TABLE))
         SELECT *
           FROM T PIVOT(MAX(WEI1) FOR(DAYS) IN('01' DAY_01,
                                               '02' DAY_02,
                                               '03' DAY_03,
                                               '04' DAY_04,
                                               '05' DAY_05,
                                               '06' DAY_06,
                                               '07' DAY_07,
                                               '08' DAY_08)))
UNION
  FROM (WITH T AS (SELECT COR_ID, COR_COD, WEI2, DAYS, 'WEI2' WEI_TYPE
                     FROM (TABLE))
         SELECT *
           FROM T PIVOT(MAX(WEI2) FOR(DAYS) IN('01' DAY_01,
                                               '02' DAY_02,
                                               '03' DAY_03,
                                               '04' DAY_04,
                                               '05' DAY_05,
                                               '06' DAY_06,
                                               '07' DAY_07,
                                               '08' DAY_08)))
UNION
  FROM (WITH T AS (SELECT COR_ID, COR_COD, WEI3, DAYS, 'WEI3' WEI_TYPE
                     FROM (TABLE))
         SELECT *
           FROM T PIVOT(MAX(WEI3) FOR(DAYS) IN('01' DAY_01,
                                               '02' DAY_02,
                                               '03' DAY_03,
                                               '04' DAY_04,
                                               '05' DAY_05,
                                               '06' DAY_06,
                                               '07' DAY_07,
                                               '08' DAY_08)))  


如何在不使用union的情况下更改此查询
   来自此的结果: that result from this:  

对此: to this:  
请帮帮我

1 个答案:

答案 0 :(得分:0)

你有一张桌子,上面有几个wei列和不同的行。并且您希望结果包含几天的列和weis的单独行。所以这是一个转换,行到列列到行。

您的查询看起来适合此任务。只是,您使用的UNION应该是UNION ALLUNION ALL将记录粘合在一起,这就是你想要的。 UNION执行相同操作,但也会查找要删除的重复项。但是,您的三个部分查询不会产生重复 - 它们至少在wei_type中有所不同。将UNION更改为UNION ALL,因此DBMS不必执行额外的工作,这会导致查询速度稍快。

以下是您在桌面上使用UNIONUNION ALL的替代查询。它与weis交叉连接以生成这些行,然后聚合/转动以从日行到列。

select 
  cor_id, cor_cod, wei_type, day_01, day_02, day_03, day_04, day_05, day_06, day_07, day_08
from
(
  select
    t.cor_id, t.cor_cod, t.days, w.wei_type,
    case w.wei_type when 'WEI1' then t.wei1 when 'WEI2' then t.wei2 else t.wei3 end as wei
  from thetable t
  cross join 
  (
    select 'WEI1' as wei_type from dual
    union all
    select 'WEI2' as wei_type from dual
    union all
    select 'WEI3' as wei_type from dual
  ) w
)
pivot 
(
   max(wei) for(days) in 
   (
     '01' day_01, '02' day_02, '03' day_03, '04' day_04,
     '05' day_05, '06' day_06, '07' day_07, '08' day_08
   )
)
order by cor_id, cor_cod, wei_type;

这与条件聚合相同,而不是PIVOT完全相同。

select 
  cor_id, cor_cod, wei_type,
  max(case when days = '01' then wei end) as day_01,
  max(case when days = '02' then wei end) as day_02,
  max(case when days = '03' then wei end) as day_03,
  max(case when days = '04' then wei end) as day_04,
  max(case when days = '05' then wei end) as day_05,
  max(case when days = '06' then wei end) as day_06,
  max(case when days = '07' then wei end) as day_07,
  max(case when days = '08' then wei end) as day_08
from
(
  select
    t.cor_id, t.cor_cod, t.days, w.wei_type,
    case w.wei_type when 'WEI1' then t.wei1 when 'WEI2' then t.wei2 else t.wei3 end as wei
  from thetable t
  cross join 
  (
    select 'WEI1' as wei_type from dual
    union all
    select 'WEI2' as wei_type from dual
    union all
    select 'WEI3' as wei_type from dual
  ) w
)
group by cor_id, cor_cod, wei_type
order by cor_id, cor_cod, wei_type;