【问题标题】:MySQL query with join + count for a specific user in DB数据库中特定用户的连接 + 计数的 MySQL 查询
【发布时间】:2019-04-12 15:06:44
【问题描述】:

我想使用查询从多个表中获取多个实体的总和。 具体来说,我想要用户的设备和消息计数。此外,该用户最后收到的消息的时间戳。 我有 3 张桌子:

用户

id     name     (other fields)
1      Mike     ...
2      John     ...
3      Yay      ...
4      Jim      ...

设备

id     user_id   (other fields)
1      1         ...
2      1         ...
3      1         ...
4      2         ...

消息

id     device_id   message    time                   (other fields)
1      1           Hi         2019-04-07 12:06:44    ...
2      1           Hey        2019-04-06 12:06:44    ...
3      2           Sup        2019-04-05 12:06:44    ...
4      3           Ok         2019-04-04 12:06:44    ...
5      4           Yay        2019-04-08 12:06:44    ...

...例如,对于用户Mike,我想最终得到:

结果

nDevices    nMessages      time 
3           4              2019-04-07 12:06:44

有什么想法吗? 提前致谢。

【问题讨论】:

    标签: mysql sql database join count


    【解决方案1】:

    加入 3 个表并计算列的不同值:

    select 
      count(distinct d.id) devicescounter, 
      count(distinct m.id) messagescounter,
      max(m.time) lastmessagetime
    from users u
    left join devices d on u.id = d.user_id 
    left join nessages m on m.device_id = d.id
    where u.name = 'Mike' 
    

    如果您想要所有用户的结果:

    select 
      u.id, u.name, 
      count(distinct d.id) devicescounter, 
      count(distinct m.id) messagescounter,
      max(m.time) lastmessagetime
    from users u
    left join devices d on u.id = d.user_id 
    left join nessages m on m.device_id = d.id
    group by u.id, u.name
    

    【讨论】:

    • 这将无法正常工作,因为没有GROUP BY。没有它,您将依赖所有内容而不是用户。
    • 这是针对特定用户的,就像 OP 想要的那样。
    • 为了简单起见,我选择了这个。谢谢。
    • 你真的需要不同的 id 吗?
    • 有一个左连接可能会多次获取同一个 id。
    【解决方案2】:

    最简单的方法是获取子查询中每个设备的消息数量和最近消息时间。

      SELECT u.id,
             COUNT(d.id) AS num_devices,
             SUM(messages) AS num_messages,
             MAX(most_recent) AS most_recent_message
        FROM users u
        JOIN devices d ON d.user_id = u.id
        JOIN (SELECT device_id,
                     COUNT() AS messages,
                     MAX(TIME) AS most_recent_message
                FROM messages
            GROUP BY device_id) m ON m.device_id = d.id
    GROUP BY u.id
    

    【讨论】:

      【解决方案3】:

      您可以尝试使用用户和设备之间的联接以及带有消息和设备子查询的内部联接

      select a.name, a.id,  count(d.user_id), t.nDevice, t.max_time 
      from Users a 
      inner join  device d on a.id = d.user_id 
      inner join  (
        select m.device_id, count(m.device_id) nDevice, max(m.time) max_time
        from Messages  m
        group by m.device_id
      ) t on t.device_id = d.id 
      group by a.name, a.id 
      

      【讨论】:

      • 不使用 nDevice 和 max_time 的聚合,MySQL 将随机选择连接表中的值之一,而不是获取总数或最近的值。 name 也不是一个很好的分组依据,因为多个用户可能具有相同的名称。
      • @drakin8564 .. 正确 .. 你也可以发布一个有效的答案。无论如何,答案已更新,通过使用 id 来强制执行组
      猜你喜欢
      • 1970-01-01
      • 2011-08-24
      • 1970-01-01
      • 2019-03-10
      • 1970-01-01
      • 2011-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多