无法从查询中获取适当的值?

时间:2018-12-10 14:51:17

标签: mysql sql group-by subquery

我想列出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”。

3 个答案:

答案 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可以自由选择该列的任何一个值。

来自MySQL doc

  

如果禁用了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键,反之亦然。