我正在将MySQL查询重写为PostgreSQL。我有文章表和另一个类别表。我需要选择所有类别,至少有一篇文章:
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
答案 0 :(得分:13)
HAVING
子句有点难以理解。我不确定MySQL如何解释它。但Postgres文档可以在这里找到:
http://www.postgresql.org/docs/9.0/static/sql-select.html#SQL-HAVING
它基本上说:
HAVING的存在会导致查询 进入分组查询即使有 没有GROUP BY子句。这是一样的 就像查询时会发生什么 包含聚合函数但不包含 GROUP BY子句。所有选定的行 被认为是一个单一的群体, 以及SELECT列表和HAVING子句 只能从中引用表列 在集合函数内。这样的 如果是,查询将发出单行 HAVING条件为真,零行如果 事实并非如此。
The same is also explained in this blog post,其中显示HAVING
如果没有GROUP BY
隐含地暗示SQL:1999标准“总计”,即GROUP BY ( )
子句(不支持的PostgreSQL)
由于您似乎不想要单行,HAVING
子句可能不是最佳选择。
考虑到您的实际查询和您的要求,只需将整个内容和JOIN
articles_categories
重写为articles
:
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)
答案 1 :(得分:0)
select * from categories c
where
exists (select 1 from article a where c.id = a.category_id);
应该没问题......或许更简单;)