幾個要點有關使用SQL:
- 在WHERE子句中不能使用列別名,但你可以在HAVING條款。這是你得到的錯誤的原因。
- 您可以使用JOIN和GROUP BY比使用相關子查詢更好地進行計算。它會更快。
- 使用HAVING子句過濾組。
這裏是我會寫這個查詢的方式:我知道這個查詢可以跳過JOIN
與T1,如查爾斯BRETANA的解決方案
SELECT t1.id, COUNT(t2.id) AS num_things
FROM t1 JOIN t2 USING (id)
GROUP BY t1.id
HAVING num_things = 5;
。但我想你可能希望查詢包含來自t1的其他列。
回覆:在註釋的問題:
的區別在於,WHERE
子句上行評價,GROUP BY
減少組每組單個行之前。在組形成後評估HAVING
子句。因此,例如,您不能通過使用HAVING
更改組的COUNT()
;你只能排除組本身。
SELECT t1.id, COUNT(t2.id) as num
FROM t1 JOIN t2 USING (id)
WHERE t2.attribute = <value>
GROUP BY t1.id
HAVING num > 5;
在上述查詢,WHERE
過濾器相匹配的條件的行,和HAVING
過濾器具有至少五個計數的基團。
,導致大多數人困惑的一點是,當他們沒有一個GROUP BY
條款,所以它似乎像HAVING
和WHERE
是可以互換的。
WHERE
在選擇列表中的表達式之前被評估。這可能並不明顯,因爲SQL語法首先將選擇列表放入。因此,通過使用WHERE
來限制行,您可以節省大量昂貴的計算。
SELECT <expensive expressions>
FROM t1
HAVING primaryKey = 1234;
如果您使用查詢像上面,在選擇列表中的表達式計算爲每一行,只能放棄大部分因爲HAVING
條件的結果。但是,下面的查詢僅計算與WHERE
條件匹配的單行的表達式。
SELECT <expensive expressions>
FROM t1
WHERE primaryKey = 1234;
因此,爲了概括,查詢由數據庫引擎根據一系列的步驟運行:
- 生成表(一個或多個)中設置的行,包括由
JOIN
產生的任何行。
- 針對該組行計算
WHERE
條件,過濾掉不匹配的行。
- 在選擇列表中爲每組行中的每個計算表達式。
- 應用列別名(注意這是一個單獨的步驟,這意味着您不能在選擇列表中的表達式中使用別名)。
- 根據
GROUP BY
條款,將組縮減爲每個組的單個行。
- 評估
HAVING
針對組的條件,過濾掉不匹配的組。
- 根據
ORDER BY
條款排序結果。
哦,我應該重新閱讀目標。你是對的。起初,我是這樣說的,「但是你失去了伯爵的信息,如果你需要這些信息呢?」 – Kev 2009-01-08 22:16:57
是的,那是有效的。奇怪的是,我以爲我一開始就嘗試過,但得到了「不允許在where子句中允許的聚合」或其他內容。我一定做了一些不同的事情。 是否有一個原因,我張貼的方式不起作用,但? – Claudiu 2009-01-08 22:17:01
我找不到它,但是在新聞組中有一個關於此的線程,並且有一個原因。我能記得的只有一個人說過(如果你重複了這個功能),在大多數情況下,計算兩次的開銷非常小。 – Kev 2009-01-08 22:20:54