2011-03-31 53 views
5

我正在將MySQL查詢重寫爲PostgreSQL。我有桌子與文章和另一個表與類別。我需要選擇所有類別,其中至少有1條:PostgreSQL中的HAVING子句

SELECT c.*,(
    SELECT COUNT(*) 
    FROM articles a 
    WHERE a."active"=TRUE AND a."category_id"=c."id") "count_articles" 
FROM articles_categories c 
HAVING (
    SELECT COUNT(*) 
    FROM articles a 
    WHERE a."active"=TRUE AND a."category_id"=c."id") > 0 

我不知道爲什麼,但這個查詢導致錯誤:

ERROR: column "c.id" must appear in the GROUP BY clause or be used in an aggregate function at character 8 

回答

11

HAVING子句是有點棘手瞭解。我不確定MySQL如何解釋它。但Postgres的文檔可以在這裏找到:

http://www.postgresql.org/docs/9.0/static/sql-select.html#SQL-HAVING

它實際上是說:

The presence of HAVING turns a query into a grouped query even if there is no GROUP BY clause. This is the same as what happens when the query contains aggregate functions but no GROUP BY clause. All the selected rows are considered to form a single group, and the SELECT list and HAVING clause can only reference table columns from within aggregate functions. Such a query will emit a single row if the HAVING condition is true, zero rows if it is not true.

The same is also explained in this blog post,這表明HAVING沒有GROUP BY如何隱含意味着SQL:1999標準的 「總計」,即一個GROUP BY ()子句(PostgreSQL不支持)

因爲你似乎不想要一個單行HAVING子句可能不是最佳選擇。

考慮到你的實際查詢和您的要求,只是重寫了整個事情,並JOINarticles_categoriesarticles

SELECT DISTINCT c.* 
FROM articles_categories c 
JOIN articles a 
ON a.active = TRUE 
AND a.category_id = c.id 

替代:

SELECT * 
FROM articles_categories c 
WHERE EXISTS (SELECT 1 
       FROM articles a 
       WHERE a.active = TRUE 
       AND a.category_id = c.id) 
+0

但是,這個結果必須分組尼韋或我必須使用DISTINCT(),不是嗎? – 2011-03-31 08:28:18

+0

當然可以。對不起......我更正了查詢並提供了替代 – 2011-03-31 08:37:43

+0

沒有「GROUP BY」的'HAVING'在SQL中是合法的,並且也受到PostgreSQL的支持。這與問題無關。 – 2011-03-31 20:39:20

0
select * from categories c 
where 
exists (select 1 from article a where c.id = a.category_id); 

應該沒事......也許更簡單;)