PostgreSQL-GROUPBY子句

PostgreSQL-GROUPBY子句,sql,postgresql,group-by,aggregate-functions,Sql,Postgresql,Group By,Aggregate Functions,我想按标签搜索,然后列出所有带有该标签的文章,以及它们匹配的给定标签的数量。例如,我可能有: Page1 - 2 (has css and php tag) Page2 - 1 (has only css tag) 查询: 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

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

 Page1 - 2 (has css and php tag)
 Page2 - 1 (has only css tag)
查询:

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
当我只输入
COUNT(t.tag)
时,查询工作正常,结果也不错。但是如果我在我的文章中添加例如
ID
,我会得到以下错误:

错误:列“a.title”必须出现在GROUP BY子句中,或在聚合函数中使用 第1行:选择计数(t.tag),从a_标签t中选择标题

如何将所述列添加到此查询?

使用“GROUP BY”子句时,需要将所有未分组到聚合函数中的列括起来。尝试将标题添加到“分组依据”列表,或选择“最小(a.title)”


首先,澄清一下,Postgres 9.1或更高版本()

在主查询时允许查询目标列表中的非GROUP BY列 密钥在GROUP BY子句中指定(Peter Eisentrut)

更多相关答案:

接下来,疑问句和in中的查询将逻辑向后推。我们要计算每篇文章匹配的标签数量,而不是有多少篇文章具有特定的标签。因此,我们需要按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
假设
id
w\u文章
的主键
但是,在执行相同操作时,此表单将更快:

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
更多信息,请参阅昨天的这个密切相关的答案:


旁白:使用通用的、非描述性的
id
作为列名是一种反模式。在两个表中都称之为
article\u id
等。更容易加入,而且您不必在查询中一直使用别名。

是的,我尝试添加MAX(a.title),然后在末尾按标记添加顺序\u count DESC。。这就解决了问题,但我不知道你为什么需要在你的案例中加入例如MIN(a.title)。。当我从MySQL迁移过来时,我认为情况并非如此,所以这就是为什么它有点奇怪:MySQL的
groupby
是非标准的,显式的不明确,MySQL不需要对选择列表中没有出现在groupby中的列使用聚合函数(如MIN或MAX)。这种行为在某些情况下会导致意外的结果,因此postgres确实有这样的要求,您已经注意到这与mysql不同。@Adrian:您可能想阅读以下内容:为了了解mysql的“松散”(不是说:不正确)
分组方式
处理.Erwin,我请你在提到其他贡献者时更加鼓励。这个问题和答案在原则上并没有错误,只是基于不同的原则而正确。提出的问题是语法问题,而不是语义问题。Adrian提供了支持语法问题的代码。答案提供了与问题相同的详细程度,并且仅限于提出的问题。作为回答,Adrian评论道,“这就解决了问题。”您选择了更详细地回答GROUP BY,并改进了语义。我完全赞成。另一个原则也可能有用。@MichaelKrebs:甚至没有任何一点冒犯或自以为是的东西。也不是有意的。对不起,我踩了你的脚趾。去除了粗体和一些噪音。只是指出问题所在,这就是我们在这里所做的。你得到了两张赞成票,得到了一半正确的答案。没那么糟。欢迎来到Stackoverflow。
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