Oracle
將前 5 名之後剩餘的“其他”相加
我有下面的查詢,它返回每個經紀公司的前 5 名總和
SELECT * FROM (SELECT b.brokerage_name AS Brokerage, SUM(c.cost) AS Cost FROM (tblquotesnew q left join tblbrokeragesnew b ON q.brokerage_id = b.id) left join tblcommissionnew c ON q.quoteid = c.quote_id WHERE c.calc_date >= Trunc(SYSDATE, 'iw') AND c.calc_date <= Trunc(SYSDATE, 'iw') + 7 - 1 / 86400 GROUP BY b.brokerage_name HAVING SUM(c.cost) IS NOT NULL ORDER BY SUM(c.cost) DESC) WHERE ROWNUM <= 5 ORDER BY ROWNUM;
在同一個查詢中,是否有可能為其他返回第六行,這將是剩餘 c.cost 的總和?
您可以使用 CTE (
WITH
子句),它預先計算所有查詢SUM(Costs)
,然後是UNION ALL
兩個查詢:一個是 CTE 中的“前 5 個”;另一個與SUM
其餘的:WITH q2 AS ( SELECT q1.*, row_number() over (order by Cost DESC) AS r FROM ( SELECT q.brokerage_id, SUM(c.cost) AS Cost FROM tblquotesnew q join tblcommissionnew c ON q.quoteid = c.quote_id WHERE c.calc_date >= Trunc(SYSDATE, 'iw') AND c.calc_date <= Trunc(SYSDATE, 'iw') + 7 - 1 / 86400 GROUP BY q.brokerage_id HAVING SUM(c.cost) IS NOT NULL ) q1 ORDER BY Cost DESC ) -- The "top 5" SELECT q2.r AS rank, b.brokerage_name AS Brokerage, q2.Cost FROM q2 LEFT JOIN tblbrokeragesnew b ON b.id = q2.brokerage_id WHERE r <= 5 UNION ALL -- The sum() of the rest (notice there is no group by; we add them all) SELECT 6 AS rank, 'Others', SUM(Cost) FROM q2 WHERE r > 5 ORDER BY rank ;
您將得到如下所示的結果:
排名 | 經紀 | 成本 ---: | :---------- | ---: 1 | 經紀1 | 8351 2 | 經紀 5 | 2231 3 | 經紀業務 4 | 2227 4 | 經紀業務 3 | 2223 5 | 經紀業務 7 | 2210 6 | 其他 | 4420
筆記:
- 您的
LEFT JOIN
ontblcommissionnew
實際上是一個INNER JOIN
,因為您在 where 中使用 tblcommissionnew 以消除所有空值。- 直到最後,您都不需要
JOIN
使用桌子。tblbrokeragesnew
Oracle 可能足以對其進行優化,但明確地執行它會更乾淨。(我假設這tblbrokeragesnew.id
是一個PK)。您可以在此處**的dbfiddle檢查所有內容(包括我假設的表定義)
差不多一樣。我的範例使用 hr.EMPLOYEES 展示表:
select case when rn <= 5 then to_char(department_id) else 'Others' end dept, sum(ss) total from ( select department_id, sum(salary) ss, row_number() over ( order by sum(salary) desc ) rn from employees group by department_id order by ss desc ) group by case when rn <= 5 then to_char(department_id) else 'Others' end order by max(ss) desc;