PostgreSQL - GROUP BY子句

Adr*_*ian 4 sql postgresql group-by aggregate-functions

我想按标签搜索,然后列出所有带有该标签的文章,以及它们匹配的给定标签的数量.例如,我可能有:

 Page1 - 2 (has css and php tag)
 Page2 - 1 (has only css tag)
Run Code Online (Sandbox Code Playgroud)

查询:

SELECT COUNT(t.tag)
FROM a_tags t
JOIN w_articles2tag a2t ON a2t.tag = t.id 
JOIN w_article a ON a.id = a2t.article 
WHERE t.tag = 'css' OR t.tag = 'php'
GROUP BY t.tag
LIMIT 9
Run Code Online (Sandbox Code Playgroud)

当我只把COUNT(t.tag)查询工作,我得到了好结果.但如果我追加ID我的文章,我会得到以下错误:

错误:列"a.title"必须出现在GROUP BY子句中或用于聚合函数LINE 1:SELECT COUNT(t.tag),a.title FROM a_tags t

如何将这些列添加到此查询?

Mic*_*ebs 8

使用"GROUP BY"子句时,需要包含未在聚合函数中分组的所有列.尝试将标题添加到GROUP BY列表,或选择"min(a.title)".

SELECT COUNT(t.tag), a.title FROM a_tags t
JOIN w_articles2tag a2t ON a2t.tag = t.id 
JOIN w_article a ON a.id = a2t.article 
WHERE t.tag = 'css' OR t.tag = 'php' GROUP BY t.tag, a.title LIMIT 9
Run Code Online (Sandbox Code Playgroud)

  • MySQL的`group by`是非标准和模糊的http://stackoverflow.com/a/1777448/375874 (3认同)

Erw*_*ter 6

首先,澄清Postgres 9.1或更高版本(引用9.1的发行说明)......

在GROUP BY子句中指定主键时,允许查询目标列表中的非GROUP BY列(Peter Eisentraut)

更多相关答案:
使用Rails和PostgreSQL返回带有出现次数的分组列表

接下来,问题和@Michael答案中的查询得到了倒退的逻辑.我们想要计算每篇文章匹配的标签数量,而不是有多少文章有特定标签.所以我们需要GROUP BY w_article.id,而不是a_tags.id.

列出具有该标记的所有文章,以及它们匹配的给定标记的数量

为了解决这样的:

SELECT COUNT(t.tag) AS ct, a.* -- any column from a allowed ...
FROM   a_tags         t
JOIN   w_articles2tag a2t ON a2t.tag = t.id 
JOIN   w_article      a   ON a.id = a2t.article 
WHERE  t.tag IN ('css', 'php')
GROUP  BY a.id           -- ... since grouped by pk column of a
LIMIT  9
Run Code Online (Sandbox Code Playgroud)

假设id是主键w_article.
但是,在执行相同操作时,此表单会更快:

SELECT a.*, ct
FROM  (
   SELECT a2t.article AS id, COUNT(*) AS ct
   FROM   a_tags         t
   JOIN   w_articles2tag a2t ON a2t.tag = t.id 
   GROUP  BY a.article 
   LIMIT  9      -- LIMIT early - cheaper
   ) sub
JOIN   w_article a USING (id);  -- attached alias to article in the sub
Run Code Online (Sandbox Code Playgroud)

更多来自昨天的这个密切相关的答案:
为什么以下连接会显着增加查询时间?

暂且不说:使用通用的非描述性id列名作为反模式.article_id在两个表中调用它等.更容易加入,您不必一直在查询中使用别名.