你好,我有如下查询 这个执行时间很长。 请介绍我尝试不同的解决方案 .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:
请帮帮我
答案 0 :(得分:0)
你有一张桌子,上面有几个wei列和不同的行。并且您希望结果包含几天的列和weis的单独行。所以这是一个转换,行到列和列到行。
您的查询看起来适合此任务。只是,您使用的UNION
应该是UNION ALL
。 UNION ALL
将记录粘合在一起,这就是你想要的。 UNION
执行相同操作,但也会查找要删除的重复项。但是,您的三个部分查询不会产生重复 - 它们至少在wei_type
中有所不同。将UNION
更改为UNION ALL
,因此DBMS不必执行额外的工作,这会导致查询速度稍快。
以下是您在桌面上使用UNION
或UNION 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;