4

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

 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 行:SELECT COUNT(t.tag), a.title FROM a_tags t

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

4

2 回答 2

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
于 2013-09-24T20:44:56.397 回答
7

Postgres 9.1 或更高版本,引用 9.1 的发行说明...

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

SQL 标准允许这种行为,并且由于主键,结果是明确的。

有关的:

问题和@Michael 的答案中的查询具有向后的逻辑。我们要计算每篇文章有多少标签匹配,而不是有多少文章具有某个标签。所以我们需要GROUP BY w_article.id,而不是通过a_tags.id

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

解决这个问题:

SELECT count(t.tag) AS ct, a.*  -- any column from table 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 PK is in GROUP BY
LIMIT  9;

假设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 1
   LIMIT  9      -- LIMIT early - cheaper
   ) sub
JOIN   w_article a USING (id);  -- attached alias to article in the sub

昨天密切相关的答案:

于 2013-09-24T22:48:07.673 回答