2009-01-08 94 views
1

我有這樣的查詢:PostgreSQL - 相關的子查詢失敗?

SELECT t1.id, 
    (SELECT COUNT(t2.id) 
    FROM t2 
    WHERE t2.id = t1.id 
     ) as num_things 
FROM t1 
WHERE num_things = 5; 

我們的目標是讓所有在其他表中出現5次的元素的ID。然而,我得到這個錯誤:

ERROR: column "num_things" does not exist 
SQL state: 42703 

我可能在這裏做一些愚蠢的事情,因爲我對數據庫有些不熟悉。有沒有辦法解決這個問題,所以我可以訪問num_things?或者,如果沒有,是否有其他方法來實現這一結果?

回答

1

我想你可以只重寫查詢,如下所示:

SELECT t1.id 
FROM t1 
WHERE (SELECT COUNT(t2.id) 
    FROM t2 
    WHERE t2.id = t1.id 
     ) = 5; 
+0

哦,我應該重新閱讀目標。你是對的。起初,我是這樣說的,「但是你失去了伯爵的信息,如果你需要這些信息呢?」 – Kev 2009-01-08 22:16:57

+0

是的,那是有效的。奇怪的是,我以爲我一開始就嘗試過,但得到了「不允許在where子句中允許的聚合」或其他內容。我一定做了一些不同的事情。 是否有一個原因,我張貼的方式不起作用,但? – Claudiu 2009-01-08 22:17:01

+0

我找不到它,但是在新聞組中有一個關於此的線程,並且有一個原因。我能記得的只有一個人說過(如果你重複了這個功能),在大多數情況下,計算兩次的開銷非常小。 – Kev 2009-01-08 22:20:54

10

幾個要點有關使用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條款,所以它似乎HAVINGWHERE是可以互換的。

WHERE在選擇列表中的表達式之前被評估。這可能並不明顯,因爲SQL語法首先將選擇列表放入。因此,通過使用WHERE來限制行,您可以節省大量昂貴的計算。

SELECT <expensive expressions> 
FROM t1 
HAVING primaryKey = 1234; 

如果您使用查詢像上面,在選擇列表中的表達式計算爲每一行,只能放棄大部分因爲HAVING條件的結果。但是,下面的查詢僅計算與WHERE條件匹配的單行的表達式。

SELECT <expensive expressions> 
FROM t1 
WHERE primaryKey = 1234; 

因此,爲了概括,查詢由數據庫引擎根據一系列的步驟運行:

  1. 生成表(一個或多個)中設置的行,包括由JOIN產生的任何行。
  2. 針對該組行計算WHERE條件,過濾掉不匹配的行。
  3. 在選擇列表中爲每組行中的每個計算表達式。
  4. 應用列別名(注意這是一個單獨的步驟,這意味着您不能在選擇列表中的表達式中使用別名)。
  5. 根據GROUP BY條款,將組縮減爲每個組的單個行。
  6. 評估HAVING針對組的條件,過濾掉不匹配的組。
  7. 根據ORDER BY條款排序結果。
3

所有其他建議會的工作,而是要回答你的基本的問題就足夠寫

SELECT id From T2 
    Group By Id 
    Having Count(*) = 5 
0

試試這個

SELECT t1.id, 
    (SELECT COUNT(t2.id) as myCount 
    FROM t2 
    WHERE t2.id = t1.id and myCount=5 
     ) as num_things 
FROM t1 
3

我想提一提,在PostgreSQL的在子句中無法使用別名列。

SELECT usr_id AS添加my_id FROM用戶HAVING添加my_id = 1

不會工作。

是行不通又如:

SELECT su.usr_id AS添加my_id,COUNT(*)AS VAL FROM sys_user蘇GROUP BY su.usr_id HAVING值> = 1

會有是相同的錯誤:val列未知。

林highliting這是因爲比爾Karwin寫的東西Postgres的不是真的。

「你不能在WHERE子句中使用列別名,但你可以在HAVING子句中這是你得到了錯誤的原因。 「