[英]How do I combine two queries (union all) into one row?
在嘗試將多個查詢中的信息轉換為單行時,我遇到了一個棘手的情況。
請考慮下表:
CpuUage:
Time time
Group char(10)
Subsys char(4)
Jobs int
Cpu int
持有以下數據:
Time Group Subsys Jobs Cpu
----- ------ ------ ---- ---
00:00 group1 NORM 1 101 (grp1-norm) A1
01:00 group1 SYS7 3 102 (grp1-sys7) A2
01:00 group1 NORM 5 104 (grp1-norm) A1
02:00 group1 NORM 7 108 (grp1-norm) A1
02:00 group2 NORM 9 116 (grp2-norm) B1
02:00 group3 SYS7 11 132 (grp3-sys7) C2
03:00 group1 SYS7 13 164 (grp1-sys7) A2
03:00 group1 IGNR 99 228 (grp1-ignr) --
右側的標記(例如, A1
)是下面報告中每行應該影響的部分。
我需要一個查詢,可以為每個用戶組返回一行,但有一個附帶條件。 Jobs
和Cpu
的值必須根據子系統ID進入不同的列,我只對SYS7
和NORM
子系統ID感興趣。
因此,例如,我們需要以下內容( A/B/1/2
位是交叉引用,返回上面的行):
<------ 1 ------> <------ 2 ------>
Group NormJobs NormCpu Sys7Jobs Sys7Cpu
------ -------- ------- -------- -------
A: group1 13 313 16 266
B: group2 9 116 0 0
C: group3 0 0 11 164
我們的舊報告解決方案可以運行多個查詢(使用union all
),然后對行進行后處理以組合具有相同組名的行,以便:
Group NormJobs NormCpu Sys7Jobs Sys7Cpu
------ -------- ------- -------- -------
group1 13 313 0 0
group1 0 0 16 266
按照以下方式合並在一起:
select groupname, sum(jobs), sum(cpu), 0, 0 from tbl
where subsys = 'NORM'
group by groupname
union all
select groupname, 0, 0, sum(jobs), sum(cpu) from tbl
where subsys = 'SYS7'
group by groupname
不幸的是,我們的新解決方案不允許進行后處理,所有這些都必須在SQL查詢中完成。
請記住,可能存在具有SYS7
行, NORM
行,兩者或兩者的組,實現此目的的最佳方法是什么?
我想過從外部選擇中查詢表格,但可能會產生性能影響。
此外,這將是一個痛苦,因為我必須使外部查詢包括NORM和SYS7子系統,然后為每個字段運行子查詢(我不能只為NORM
作業的外部查詢,因為存在一個組只有SYS7
行才會被捕獲。)
您是否可以編織任何左中間內側越位魔法來提出可行的解決方案?
我更喜歡與供應商無關的解決方案,但是,如果您必須特定於供應商,則該平台是DB2。 不過,其他平台至少可以給我一些嘗試的想法,所以我很高興看到它們。
我不明白子查詢的問題,看起來它應該同樣快:
select
sub.gn as groupname,
sum(sub.nj) as NormJobs, sum(sun.nc) as NormCpu,
sum(sub.sj) as Sys7Jobs, sum(sub.sc) as Sys7Cpu
from (
select
groupname as gn,
sum(jobs) as nj, sum(cpu) as nc,
0 as sj, 0 as sc
from tbl
where subsys = 'NORM'
group by groupname
union all select
groupname as gn,
0 as nj, 0 as nc,
sum(jobs) as sj, sum(cpu) as sc
from tbl
where subsys = 'SYS7'
group by groupname
) as sub
group by sub.gn
order by 1
這是一個數據透視表查詢。 (如果您需要更多信息,請搜索。)
您想要的查詢結構類似於以下內容:
SELECT groupname,
SUM(CASE WHEN subsys = 'NORM' THEN jobs ELSE 0 END) AS NormJobs,
SUM(CASE WHEN subsys = 'NORM' THEN cpu ELSE 0 END) AS NormCpu,
SUM(CASE WHEN subsys = 'SYS7' THEN jobs ELSE 0 END) AS Sys7Jobs,
SUM(CASE WHEN subsys = 'SYS7' THEN cpu ELSE 0 END) AS Sys7Cpu,
SUM(CASE WHEN subsys NOT IN ('NORM', 'SYS7') THEN jobs ELSE 0 END) AS OtherJobs,
SUM(CASE WHEN subsys NOT IN ('NORM', 'SYS7') THEN cpu ELSE 0 END) AS OtherCpu
FROM ???
GROUP BY groupname
這是一個典型的數據透視查詢 - 以下是使用CASE語句執行此操作的方法:
SELECT t.group,
SUM(CASE
WHEN t.subsys = 'NORM' THEN t.jobs
ELSE NULL
END CASE) AS NormJobs,
SUM(CASE
WHEN t.subsys = 'NORM' THEN t.cpu
ELSE NULL
END CASE) AS NormCpu,
SUM(CASE
WHEN t.subsys = 'SYS7' THEN t.jobs
ELSE NULL
END CASE) AS Sys7Jobs,
SUM(CASE
WHEN t.subsys = 'SYS7' THEN t.cpu
ELSE NULL
END CASE) AS Sys7Cpu
FROM CPUUSAGE t
GROUP BY t.group
不幸的是,當Oracle / SQL Server / MySQL / Postgres沒有時,DB2的CASE語句需要以END CASE
結束。 那么,PLSQL支持END CASE
......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.