我想列出companyId,并且大多数出现可注释类型(0,1,2)。
这是子查询
select a.companyId, a.commentable, count(1) _count
from article a
group by a.companyId, a.commentable
| companyId | commentable | _count |
|-----------|-------------|--------|
| 1 | 0 | 1 |
| 1 | 1 | 1 |
| 2 | 0 | 7759 |
| 2 | 1 | 7586 |
| 2 | 2 | 7856 |
| 3 | 0 | 7828 |
| 3 | 1 | 7866 |
| 3 | 2 | 7706 |
| 4 | 0 | 7851 |
| 4 | 1 | 7901 |
| 4 | 2 | 7738 |
| 5 | 0 | 7775 |
| 5 | 1 | 7884 |
| 5 | 2 | 7602 |
| 25 | 0 | 7888 |
| 25 | 1 | 7939 |
| 25 | 2 | 7784 |
例如以上 最可注释的类型出现在companyId = 4为7901且可注释类型为1的情况下。在下面的查询中,我看到4-0-7901,但我期望的是4-1-7901
SELECT x.companyId, x.commentable, MAX(x._count) _count
FROM
( SELECT a.companyId, a.commentable, COUNT(1) _count
FROM article a
GROUP BY a.companyId, a.commentable
) AS X
GROUP BY x.companyId;
companyId commentable _count
1 0 1
2 0 7856
3 0 7866
4 0 7901
5 0 7884
25 0 7939
Expected result
companyId commentable _count
1 0 1
2 2 7856
3 1 7866
4 1 7901
5 1 7884
25 1 7939
我不明白“为什么所有可注释列都为“ 0”。
答案 0 :(得分:3)
您需要在这里加入大量丑陋的内容。在下面的查询中,您可以查看公司的GROUP BY
查询,并注释输入基本工作单位。该查询本身显示,别名为t1
。在别名t2
中,我们仅对commentable
进行子查询和汇总,以找到每种此类注释类型的最大数量。为此,我们重新加入t1
,以仅限制拥有最大人数的公司。
SELECT
t1.companyId,
t1.commentable,
t1.cnt
FROM
(
SELECT companyId, commentable, COUNT(*) cnt
FROM article
GROUP BY companyId, commentable
) t1
INNER JOIN
(
SELECT companyId, MAX(cnt) max_cnt
FROM
(
SELECT companyId, commentable, COUNT(*) cnt
FROM article
GROUP BY companyId, commentable
) t
GROUP BY companyId
) t2
ON t1.companyId = t2.companyId AND t1.cnt = t2.max_cnt;
顺便说一句,在MySQL 8+中,事情变得更好了,我们可以在其中利用分析功能:
WITH cte AS (
SELECT companyId, commentable, COUNT(*) cnt,
ROW_NUMBER() OVER (PARTITION BY commentable ORDER BY COUNT(*) DESC) rn
FROM article
GROUP BY companyId, commentable
)
SELECT companyId, commentable, cnt
FROM cte
WHERE rn = 1;
答案 1 :(得分:1)
原因commentable
不是group by
列之一。在这种情况下,禁用ONLY_FULL_GROUP_BY
后,MySQL可以自由选择该列的任何一个值。
如果禁用了ONLY_FULL_GROUP_BY,则对标准SQL使用GROUP BY的MySQL扩展允许选择列表,HAVING条件或ORDER BY列表引用未聚合的列,即使这些列在功能上不依赖于GROUP BY列也是如此。这导致MySQL接受前面的查询。在这种情况下,服务器可以从每个组中自由选择任何值,因此,除非它们相同,否则选择的值是不确定的,这可能不是您想要的。
答案 2 :(得分:1)
您可以使用having
子句来做到这一点:
SELECT a.companyId, a.commentable, COUNT(*) as _count
FROM article a
GROUP BY a.companyId, a.commentable
HAVING COUNT(*) = (SELECT COUNT(*)
FROM article a2
WHERE a2.companyId = a.companyId
GROUP BY a2.commentable
ORDER BY COUNT(*) DESC
LIMIT 1
);
如果发生平局,您将获得多行。如果每个公司只需要一行,则可以在commentable
中使用HAVING
进行比较:
SELECT a.companyId, a.commentable, COUNT(*) as _count
FROM article a
GROUP BY a.companyId, a.commentable
HAVING a.commentable = (SELECT a2.commentable
FROM article a2
WHERE a2.companyId = a.companyId
GROUP BY a2.commentable
ORDER BY COUNT(*) DESC
LIMIT 1
);
正如其他人所述,您的问题是GROUP BY
的滥用。 SELECT
中未聚合的列需要匹配GROUP BY
键,反之亦然。