【问题标题】:MYSQL LEFT JOIN and COUNT and GROUP BYMYSQL LEFT JOIN 和 COUNT 和 GROUP BY
【发布时间】:2015-01-16 14:14:32
【问题描述】:

我发现了几个关于该任务的线程,但都没有真正帮助我,或者我没有足够的经验来理解它。

我正在使用 mysql 并且有两个表 useruser_rh。我想要一个用户名列表(按名称排序),并在user_rh 中包含相应数量的条目。

      `user`                `user_rh`
------------------     ------------------
| `uid` | `name` |     | `uid` | `zaid` |
------------------     ------------------
|   1   | Bob    |     |   2   |    4   |
|   2   | John   |     |   2   |    7   |
|   3   | Fred   |     |   3   |    2   |
|   4   | Peter  |     ------------------
------------------

所以结果应该是这样的:

--------------------
| `name` | `count` |
--------------------
| Bob    |    0    |
| Fred   |    1    |
| John   |    2    |
| Peter  |    0    |
--------------------

我试过这个查询:

SELECT
    `user`.`name`,
    `user_rh`.`uid`
FROM
    `user`
LEFT JOIN
    `user_rh`
ON (`user_rh`.`uid`=`user`.`uid`)
ORDER BY
    `user`.`name`

它以正确的方式进行,但这不会返回计数值:

------------------
| `name` | `uid` |
------------------
| Bob    |  NULL |
| John   |   2   |
| John   |   2   |
| Fred   |   1   |
| Peter  |  NULL |
------------------

我以为我只是添加了 COUNT() 和 GROUP BY 命令:

SELECT
    `user`.`name`, 
    COUNT(`user_rh`.`uid`) AS `count`
FROM
    `user`
LEFT JOIN
    `user_rh`
    ON (`user_rh`.`uid`=`user`.`uid`)
GROUP BY
    `user_rh`.`uid`
ORDER BY
    `user`.`name`

但它向我展示了这样的东西。首先,它提供一个排序后的名称列表,其中包含 count!=0,列表的最后一个条目是表 user 的第一个条目,它具有 count=0。

------------------
| `name` | `uid` |
------------------
| John   |   2   |
| Fred   |   1   |
| Bob    |   0   |
------------------

我想,我只是以错误的方式组合命令。

【问题讨论】:

    标签: mysql count group-by left-join


    【解决方案1】:

    您的第二个查询很好。只需从第一个表中按用户分组。否则你会把你的left join 变成inner join

    SELECT
        u.name, 
        COUNT(rh.uid) AS cnt
    FROM
        `user` u
    LEFT JOIN
        user_rh rh
        ON (rh.uid = u.uid)
    GROUP BY
        u.uid, u.name
    ORDER BY
        u.name
    

    【讨论】:

    • 谢谢............!!!!!那行得通........还有两个问题可以正确理解它。 1) 为什么 GROUP BY user_rh.uid 将 LEFT JOIN 转换为 INNER JOIN? 2) 为什么 GROUP BY 命令中多了个user.name
    • 1.如果您按某些内容进行分组,则它必须存在- LEFT JOIN 正好相反- 加入表并且即使无法建立关系也不要减少数据。 2. 您应该始终对您选择的所有列进行分组,不要聚合。只有 MySQL 允许这样做。
    【解决方案2】:
    1. 它不会将您的 left join 转换为 inner join。当链接到用户时,它只是根据 user_rh 中的 uid 进行分组。您有 3 个不同的 uid(NULL、2 和 1),这就是结果中只有 3 行的原因。

    2. 当您使用分组子句时,您只能选择具有分组聚合的字段(如 COUNT、SUM、AVG..)或分组子句中可用的字段。您可以省略分组,但 Mysql 会自己进行分组,但结果可能不可靠,因为它会选择第一个可用的分组。这就是您在 3 行结果中显示 Bob 的原因。

    【讨论】:

      猜你喜欢
      • 2020-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-16
      相关资源
      最近更新 更多