我有一個查詢對專案進行分組,選擇一個組中的專案數,以及該組在 where 子句中未過濾掉的所有專案中所占的百分比
我想洗掉其中包含兩個或更少專案的任何組,以便減少占整個資料集一小部分的結果。
這是我的(簡化)查詢:
select count(i.itemId) as itemCount,
concat(format(100 * count(i.itemId) / sum(count(i.itemId)) over (), 2), '%') as totalPercentage
from thing t
join item i on t.thingId = i.thingId
where t.createdDate > startdate and t.createdDate < enddate
group by t.thingId
order by count(i.itemId) desc, t.thingId desc;
我想我應該添加一個這樣的子句:
...
group by t.thingId
having count(i.itemId) > 2
order by count(i.itemId) desc, t.thingId desc;
會解決問題,但是當我這樣做時,結果顯示的總百分比現在不準確,因為sum(count(i.itemId)) over ()現在忽略了其中包含 2 個或更少專案的組。
我知道可以通過將此查詢設為內部查詢然后在此查詢之外的選擇中進行過濾來實作此目的,但我不希望這樣做,因為在我的團隊中,我們盡量避免內部查詢,除非他們是必要的。
我也知道可以制作一個臨時表,并通過從該臨時表中選擇來過濾它,但我什至不想深入研究,因為它看起來很丑。
TLDR:是否可以從選擇結果中過濾掉組,但它們是否仍然包含在sum() over ()沒有任何惡作劇的子句中?
uj5u.com熱心網友回復:
首先計算百分比并將其用作子查詢,然后再過濾,因為任何過濾都會洗掉您需要的行
你和
SELECT
itemCount,totalPercentage
FROM
(select
t.thingId,
count(i.itemId) as itemCount,
concat(format(100 * count(i.itemId) / sum(count(i.itemId)) over (), 2), '%') as totalPercentage
from thing t
join item i on t.thingId = i.thingId
where t.createdDate > startdate and t.createdDate < enddate
group by t.thingId) t1
WHERE intemCount = 2
order by itemCount desc, thingId desc;
uj5u.com熱心網友回復:
一般來說,如果沒有子查詢的幫助,就不可能在 SQL 中計算百分比。要生成百分比,您需要除以總數,這需要單獨的聚合查詢。
我希望你的團隊關于子查詢的政策實際上是“盡可能避免依賴的 a/k/a 相關子查詢”。這些是影響性能的因素。作為政策問題避免所有子查詢?這有點像在編程中避免使用子程式——它禁止使用主要語言功能。
uj5u.com熱心網友回復:
您可以嘗試使用 case 陳述句,以便它給出空百分比,然后在下一階段過濾掉空值,無論是 sql 還是某些前端代碼。
...
case when count(i.itemId) > 2
then concat(format(100 * count(i.itemId) / sum(count(i.itemId)) over (), 2), '%') end as
totalPercentage
...
這可能只會增加計算時間,或者可以像其他答案中提到的那樣使用外部查詢來過濾掉它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/342394.html
上一篇:MySQL簡單但速度慢的查詢
