寻找一个按小时分组并收集用户信息的查询

时间:2019-05-17 11:52:10

标签: mysql sql join

我想创建一个查询,该查询可以为我提供用户ID的消息数+发布时间。

我有一个0-23小时的小时表,我有一个历史表,其中包含用户发布的消息和添加的日期。

现在,我想创建一个显示给我的结果:

  • 每个小时应该有一个来自用户表的所有用户

  • 即使历史记录表中没有user_id的记录,该用户已发布的消息数

我已经尝试过该查询,唯一的错误是它没有显示每小时的用户ID

SELECT COUNT(*) AS messages, h.hour AS `Hour`, c.user_id, p.name
FROM history c
  INNER JOIN users p ON c.user_id = p.user_id
  RIGHT JOIN hours h ON h.hour = HOUR(c.`date_added`)
    AND YEAR(`date_added`) = '2019' AND MONTH(`date_added`) = '03' AND DAY(`date_added`) = '06'
GROUP BY h.hour, c.user_id
ORDER BY h.hour ASC;

提琴:http://sqlfiddle.com/#!9/5c60d5b

-感谢所有查询!

4 个答案:

答案 0 :(得分:1)

hoursusers进行交叉联接,对history进行左联接:

select 
  t.hour, t.user_id, t.name, sum(history_id is not null) messages
from (select * from hours cross join users) t
left join (
  select * from history
  where
    year(date_added) = 2019 and month(date_added) = 3 and day(date_added) = 6
) h 
on h.user_id = t.user_id and t.hour = hour(h.date_added)
group by t.hour, t.user_id, t.name

请参见demo
结果:

> hour | user_id | name  | messages
>   .. |........ |...... |.........
>   14 |       4 | test4 |        0
>   15 |       1 | test  |        0
>   15 |       2 | test2 |        0
>   15 |       3 | test3 |        0
>   15 |       4 | test4 |        0
>   16 |       1 | test  |        1
>   16 |       2 | test2 |        0
>   16 |       3 | test3 |        5
>   16 |       4 | test4 |        8
>   17 |       1 | test  |        0
>   .. |........ |...... |.........

我在示例数据的user_id = 4表中添加了users,因为它已包含在history中。

答案 1 :(得分:0)

要在两个不相关的表之间进行所有可能的组合,可以使用CROSS JOIN。因此,下面的查询达到了-“每个小时应该有来自用户表的所有用户”

SELECT h.hour, u.user_id
FROM hours h
CROSS JOIN users u

答案 2 :(得分:0)

尝试在分组依据中使用左联接nad小时date_add

SELECT COUNT(*) AS messages,  hour(date_added)  , c.user_id, p.name
FROM history c
 INNER JOIN users p ON c.user_id = p.user_id
  LEFT JOIN hours h ON h.hour = hour(date_added) 
AND YEAR(`date_added`) = '2019' AND MONTH(`date_added`) = '03' AND DAY(`date_added`) = '06'
GROUP BY hour(date_added) , c.user_id
ORDER BY h.hour ASC;

答案 3 :(得分:0)

如果您一直追随所有用户,无论他们是否收到消息,那么下面的代码可能就是您想要的。它包含两个子查询,以允许将邮件计数表添加到用户和小时的完整列表中。

SELECT messages, h.hour AS `hour`, h.user_id, h.name
FROM (
  SELECT COUNT(*) AS messages, HOUR(c.`date_added`) as `hour`, c.user_id, p.name
  FROM users p
  INNER JOIN history  c
  ON c.user_id = p.user_id
  WHERE YEAR(`date_added`) = '2019' AND MONTH(`date_added`) = '03' AND DAY(`date_added`) = '06'
  GROUP BY HOUR(c.`date_added`), c.user_id, p.name
  ) z
  right join
  (
    SELECT h.hour, u.user_id, u.name
    FROM hours h
    CROSS JOIN users u
  ) h ON h.hour = z.hour
      AND h.user_id = z.user_id
 ORDER BY hour