Wil*_*son 1 oracle pivot reporting oracle-12c
我有一张road_insp桌子:
create table road_insp
(
insp_id int,
road_id int,
insp_year int,
condition number(10,2)
);
insert into road_insp (insp_id, road_id, insp_year, condition) values ( 1, 100, 2009, 5);
insert into road_insp (insp_id, road_id, insp_year, condition) values ( 2, 100, 2011, 3);
insert into road_insp (insp_id, road_id, insp_year, condition) values ( 3, 102, 2009, 9);
insert into road_insp (insp_id, road_id, insp_year, condition) values ( 4, 102, 2010, 7);
insert into road_insp (insp_id, road_id, insp_year, condition) values ( 5, 102, 2013, 5);
insert into road_insp (insp_id, road_id, insp_year, condition) values ( 6, 103, 2009, 10);
insert into road_insp (insp_id, road_id, insp_year, condition) values ( 7, 103, 2011, 8);
insert into road_insp (insp_id, road_id, insp_year, condition) values ( 8, 103, 2012, 6);
insert into road_insp (insp_id, road_id, insp_year, condition) values ( 9, 103, 2013, 4);
commit;
select
insp_id,
road_id,
insp_year,
condition
from
road_insp;
INSP_ID ROAD_ID INSP_YEAR CONDITION
---------- ---------- ---------- ----------
1 100 2009 5
2 100 2011 3
3 102 2009 9
4 102 2010 7
5 102 2013 5
6 103 2009 10
7 103 2011 8
8 103 2012 6
9 103 2013 4
Run Code Online (Sandbox Code Playgroud)
我想逐年比较道路状况。
我可以通过加入每年的子选择来做到这一点:
select
a.road_id,
y09.condition condition_2009,
y10.condition condition_2010,
y11.condition condition_2011,
y12.condition condition_2012,
y13.condition condition_2013
from
road_insp a
left join
(select
road_id,
condition
from
road_insp
where
insp_year = 2009
) y09
on a.road_id = y09.road_id
left join
(select
road_id,
condition
from
road_insp
where
insp_year = 2010
) y10
on a.road_id = y10.road_id
left join
(select
road_id,
condition
from
road_insp
where
insp_year = 2011
) y11
on a.road_id = y11.road_id
left join
(select
road_id,
condition
from
road_insp
where
insp_year = 2012
) y12
on a.road_id = y12.road_id
left join
(select
road_id,
condition
from
road_insp
where
insp_year = 2013
) y13
on a.road_id = y13.road_id
group by
a.road_id,
y09.condition,
y10.condition,
y11.condition,
y12.condition,
y13.condition
order by
road_id
Run Code Online (Sandbox Code Playgroud)
ROAD_ID CONDITION_2009 CONDITION_2010 CONDITION_2011 CONDITION_2012 CONDITION_2013
---------- -------------- -------------- -------------- -------------- --------------
100 5 3
102 9 7 5
103 10 8 6 4
Run Code Online (Sandbox Code Playgroud)
但是,这种方法相当繁琐。是否有更简洁的方法来旋转表格以进行年度比较?
是的,您的场景存在更简洁的旋转方法。
例如,您可以使用PIVOT 运算符:
SELECT
*
FROM
(
SELECT
road_id,
insp_year,
condition
FROM
road_insp
) derived
PIVOT
(
MAX(condition)
FOR insp_year IN
(
2009 AS condition_2009,
2010 AS condition_2010,
2011 AS condition_2011,
2012 AS condition_2012,
2013 AS condition_2013
)
)
;
Run Code Online (Sandbox Code Playgroud)
PIVOT 意味着分组,这就是为什么您可以看到 MAX() 聚合函数应用于condition而不是简单地使用condition.
隐式分组也是您在应用 PIVOT 运算符之前经常需要使用派生表的原因:所有在 PIVOT 子句中未提及的列实际上都参与了分组,因此您需要排除那些不应该是分组条件的列。对于您的特定示例,您确实需要一个派生表,因为您需要排除insp_id.
作为 PIVOT 运算符的替代方法,您可以尝试使用老式的条件聚合方法:
SELECT
road_id,
MAX(DECODE(insp_year, 2009, condition, NULL)) AS condition_2009,
MAX(DECODE(insp_year, 2010, condition, NULL)) AS condition_2010,
MAX(DECODE(insp_year, 2011, condition, NULL)) AS condition_2011,
MAX(DECODE(insp_year, 2012, condition, NULL)) AS condition_2012,
MAX(DECODE(insp_year, 2013, condition, NULL)) AS condition_2013
FROM
road_insp
GROUP BY
road_id
;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,不需要派生表,因为可以在 GROUP BY 子句中显式指定要分组的列。
—————————
两种方法都产生相同的输出,与您的连接方法生成的输出相同,如dbfiddle.uk 上的演示所示。
| 归档时间: |
|
| 查看次数: |
162 次 |
| 最近记录: |