Oracle SQL,在带联合的查询中总是显示三行
Oracle SQL, always show three lines in query with unions
我return下面的数据来自数据库。我根据状态,计算特定状态的物品数量和最旧物品的年龄。
select distinct 1, dm1.technology, dm1.name_event, count(dm1.id) as "Number of items", max(TO_CHAR(TO_DATE('20000101','yyyymmdd')+(SYSDATE - dm1.time_event),'hh24:mi:ss')) as "Time in system" from dm_procmon dm1 join dm_procmon dm2 on dm1.id = dm2.id
where dm1.name_event = 'state1' and (select count(*) from dm_procmon dm2 where dm1.id= dm2.id and dm2.name_event = 'state2') = 0
group by dm1.technology, dm1.name_event
UNION
select distinct 2, dm1.technology, dm1.name_event, count(dm1.id) as "Number of items", max(TO_CHAR(TO_DATE('20000101','yyyymmdd')+(SYSDATE - dm1.time_event),'hh24:mi:ss')) as "Time in system" from dm_procmon dm1 join dm_procmon dm2 on dm1.id = dm2.id
where dm1.name_event = 'state2' and (select count(*) from dm_procmon dm2 where dm1.id= dm2.id and dm2.name_event = 'state3') = 0
group by dm1.technology, dm1.name_event
UNION
select distinct 3, dm1.technology, dm1.name_event, count(dm1.id) as "Number of items", max(TO_CHAR(TO_DATE('20000101','yyyymmdd')+(SYSDATE - dm1.time_event),'hh24:mi:ss')) as "Time in system" from dm_procmon dm1
where dm1.name_event = 'state3' and (select count(*) from dm_procmon dm2 where dm1.id= dm2.id and dm2.name_event = 'end state') = 0
group by dm1.technology , dm1.name_event
问题是,当特定状态下有 0 个项目时,该状态的行将被忽略。这意味着如果例如状态 3 0 项目有,则该行根本不显示...
当前输出,错误
1 TECHNOLOGY NAME_EVENT Number of items Time in system
---------- -------------------- ----------------- --------------- --------------
1 Repository state1 4 00:19:51
2 Repository state2 1 00:28:21
我想要实现的输出
1 TECHNOLOGY NAME_EVENT Number of items Time in system
---------- -------------------- ----------------- --------------- --------------
1 Repository state1 4 00:19:51
2 Repository state2 1 00:28:21
3 Repository state3 0 00:00:00
您可以使用 UNION 和 NOT EXISTS.
显式添加行
例如,让我们看一个测试用例:
SQL> SELECT deptno dept, count(*) cnt FROM emp WHERE deptno = 20
2 GROUP BY deptno
3 UNION
4 SELECT deptno dept, count(*) cnt FROM emp WHERE deptno = 100
5 GROUP BY deptno
6 /
DEPT CNT
---------- ----------
20 5
SQL>
即使没有 deptno = 100 的部门,我也希望显示一行。
SQL> SELECT to_char(deptno) dept, count(*) cnt FROM emp WHERE deptno = 20
2 group by to_char(deptno)
3 UNION
4 SELECT 'No departments found' dept, 0 cnt
5 FROM dual
6 WHERE NOT EXISTS
7 (SELECT 1 FROM emp WHERE deptno = 100
8 )
9 /
DEPT CNT
---------------------------------------- ----------
20 5
No departments found 0
SQL>
在上面的示例中,没有 department = 100 的行,但我正在显示它。
检查此查询(需要 Oracle 11g):
with data1 as (
select id, technology tg,
max(decode(name_event, 'state1', 1, 0)) st1,
max(decode(name_event, 'state2', 1, 0)) st2,
max(decode(name_event, 'state3', 1, 0)) st3,
sum(decode(name_event, 'end state', 1, 0)) st4,
max(to_char(date '2000-01-01'+(sysdate - time_event), 'hh24:mi:ss')) tis
from dm_procmon group by id, technology ),
data2 as (
select tg, count(case when st1 = 1 and st2 = 0 then id end) st1,
count(case when st2 = 1 and st3 = 0 then id end) st2,
count(case when st3 = 1 and st4 = 0 then id end) st3,
max(case when st1 = 1 and st2 = 0 then tis else '00:00:00' end) tis1,
max(case when st2 = 1 and st3 = 0 then tis else '00:00:00' end) tis2,
max(case when st3 = 1 and st4 = 0 then tis else '00:00:00' end)tis3
from data1 group by tg
)
select tg technology, st state, max(noi) items, max(tis) max_time
from (
select *
from data2
unpivot (noi for st in (st1 as 'state1', st2 as 'state2', st3 as 'state3'))
unpivot (tis for ti in (tis1 as 'state1', tis2 as 'state2', tis3 as 'state3'))
)
where st=ti group by tg, st order by tg, st
我能够稍微简化这个查询,最后一部分应该是:
select tg technology, event, items, max_time
from data2
unpivot ((items, max_time) for (event, t) in (
(st1, tis1) as ('state1', null),
(st2, tis2) as ('state2', null),
(st3, tis3) as ('state3', null) ))
order by technology, event
我return下面的数据来自数据库。我根据状态,计算特定状态的物品数量和最旧物品的年龄。
select distinct 1, dm1.technology, dm1.name_event, count(dm1.id) as "Number of items", max(TO_CHAR(TO_DATE('20000101','yyyymmdd')+(SYSDATE - dm1.time_event),'hh24:mi:ss')) as "Time in system" from dm_procmon dm1 join dm_procmon dm2 on dm1.id = dm2.id
where dm1.name_event = 'state1' and (select count(*) from dm_procmon dm2 where dm1.id= dm2.id and dm2.name_event = 'state2') = 0
group by dm1.technology, dm1.name_event
UNION
select distinct 2, dm1.technology, dm1.name_event, count(dm1.id) as "Number of items", max(TO_CHAR(TO_DATE('20000101','yyyymmdd')+(SYSDATE - dm1.time_event),'hh24:mi:ss')) as "Time in system" from dm_procmon dm1 join dm_procmon dm2 on dm1.id = dm2.id
where dm1.name_event = 'state2' and (select count(*) from dm_procmon dm2 where dm1.id= dm2.id and dm2.name_event = 'state3') = 0
group by dm1.technology, dm1.name_event
UNION
select distinct 3, dm1.technology, dm1.name_event, count(dm1.id) as "Number of items", max(TO_CHAR(TO_DATE('20000101','yyyymmdd')+(SYSDATE - dm1.time_event),'hh24:mi:ss')) as "Time in system" from dm_procmon dm1
where dm1.name_event = 'state3' and (select count(*) from dm_procmon dm2 where dm1.id= dm2.id and dm2.name_event = 'end state') = 0
group by dm1.technology , dm1.name_event
问题是,当特定状态下有 0 个项目时,该状态的行将被忽略。这意味着如果例如状态 3 0 项目有,则该行根本不显示...
当前输出,错误
1 TECHNOLOGY NAME_EVENT Number of items Time in system
---------- -------------------- ----------------- --------------- --------------
1 Repository state1 4 00:19:51
2 Repository state2 1 00:28:21
我想要实现的输出
1 TECHNOLOGY NAME_EVENT Number of items Time in system
---------- -------------------- ----------------- --------------- --------------
1 Repository state1 4 00:19:51
2 Repository state2 1 00:28:21
3 Repository state3 0 00:00:00
您可以使用 UNION 和 NOT EXISTS.
显式添加行例如,让我们看一个测试用例:
SQL> SELECT deptno dept, count(*) cnt FROM emp WHERE deptno = 20
2 GROUP BY deptno
3 UNION
4 SELECT deptno dept, count(*) cnt FROM emp WHERE deptno = 100
5 GROUP BY deptno
6 /
DEPT CNT
---------- ----------
20 5
SQL>
即使没有 deptno = 100 的部门,我也希望显示一行。
SQL> SELECT to_char(deptno) dept, count(*) cnt FROM emp WHERE deptno = 20
2 group by to_char(deptno)
3 UNION
4 SELECT 'No departments found' dept, 0 cnt
5 FROM dual
6 WHERE NOT EXISTS
7 (SELECT 1 FROM emp WHERE deptno = 100
8 )
9 /
DEPT CNT
---------------------------------------- ----------
20 5
No departments found 0
SQL>
在上面的示例中,没有 department = 100 的行,但我正在显示它。
检查此查询(需要 Oracle 11g):
with data1 as (
select id, technology tg,
max(decode(name_event, 'state1', 1, 0)) st1,
max(decode(name_event, 'state2', 1, 0)) st2,
max(decode(name_event, 'state3', 1, 0)) st3,
sum(decode(name_event, 'end state', 1, 0)) st4,
max(to_char(date '2000-01-01'+(sysdate - time_event), 'hh24:mi:ss')) tis
from dm_procmon group by id, technology ),
data2 as (
select tg, count(case when st1 = 1 and st2 = 0 then id end) st1,
count(case when st2 = 1 and st3 = 0 then id end) st2,
count(case when st3 = 1 and st4 = 0 then id end) st3,
max(case when st1 = 1 and st2 = 0 then tis else '00:00:00' end) tis1,
max(case when st2 = 1 and st3 = 0 then tis else '00:00:00' end) tis2,
max(case when st3 = 1 and st4 = 0 then tis else '00:00:00' end)tis3
from data1 group by tg
)
select tg technology, st state, max(noi) items, max(tis) max_time
from (
select *
from data2
unpivot (noi for st in (st1 as 'state1', st2 as 'state2', st3 as 'state3'))
unpivot (tis for ti in (tis1 as 'state1', tis2 as 'state2', tis3 as 'state3'))
)
where st=ti group by tg, st order by tg, st
我能够稍微简化这个查询,最后一部分应该是:
select tg technology, event, items, max_time
from data2
unpivot ((items, max_time) for (event, t) in (
(st1, tis1) as ('state1', null),
(st2, tis2) as ('state2', null),
(st3, tis3) as ('state3', null) ))
order by technology, event