mysql - 如何从今天开始每 3 小时对 MySQL 中的数据进行分组?

标签 mysql sql

我想为我的一个图表检索数据,我想为它想出一个简单的解决方案,而不是执行 8 个子查询。

这是 users 表的样子:

user_id
1
2
3
4
5

这是 pts 表的样子:

id  user_id  status  points                 time
1         1       0      100  2014-08-23 03:34:54
2         4       0      100  2014-08-23 04:04:44
3         1       1      300  2014-08-23 08:34:21
4         1       0      300  2014-08-23 15:25:11
5         1       0      200  2014-08-23 22:23:12

查询看起来像这样(有一些评论,我不知道该放什么):

    "SELECT  *,
        (
            SELECT  SUM(points)
            FROM    pts
            WHERE   status = 0 
            AND     user_id = 1
            AND     time >= "THIS DAY'S 00:00" AND <= "THIS DAY'S 03:00" 
        ),
        (
            SELECT  SUM(points)
            FROM    pts
            WHERE   status = 0 
            AND     user_id = 1
            AND     time >= "THIS DAY'S 03:00" AND <= "THIS DAY'S 06:00"
        ),
        (
            SELECT  SUM(points)
            FROM    pts
            WHERE   status = 0
            AND     user_id = 1 
            AND     time >= "THIS DAY'S 06:00" AND <= "THIS DAY'S 09:00"
        ),
        (
            SELECT  SUM(points)
            FROM    pts
            WHERE   status = 0 
            AND     user_id = 1
            AND     time >= "THIS DAY'S 12:00" AND <= "THIS DAY'S 15:00"
        ),
"ETC......"
FROM    pts
WHERE   user_id = 1
AND     status  = 1
"

所以基本上查询需要在当天每 3 小时从数据库中收集数据(所以如果我使用上述选项,它将是 8 个子查询)。此外,如果该时间间隔尚未达到当前时间,则查询应返回 0/null。如果当前时间在其中一个时间间隔内,它应该返回从时间间隔开始到时间间隔结束的数据。

我想达到的结果:

id  user_id  points                                       time
1         1       0  2014-08-23 00:00:00 - 2014-08-23 03:00:00
2         1     200  2014-08-23 03:00:00 - 2014-08-23 06:00:00
3         1     300  2014-08-23 06:00:00 - 2014-08-23 09:00:00
4         1       0  2014-08-23 09:00:00 - 2014-08-23 12:00:00
5         1       0  2014-08-23 12:00:00 - 2014-08-23 15:00:00
6         1     300  2014-08-23 15:00:00 - 2014-08-23 18:00:00
7         1       0  2014-08-23 18:00:00 - 2014-08-23 21:00:00
8         1     200  2014-08-23 21:00:00 - 2014-08-23 00:00:00

这对 MySQL 来说可能吗?

最佳答案

你可以只在小时内使用聚合和算术:

select floor(hour(time) / 3) as hourgroup, sum(points)
from pts
where status = 0 and user_id = 1 and
      date(time) = "THIS DAY"
group by floor(hour(time) / 3);

对于您的特定输出:

select (hour(time) div 3) as id, user_id, sum(points),
       date('2014-08-23') + interval 3 * (hour(time) div 3) hour as starttime,
       date('2014-08-23') + interval 3 * ((hour(time) div 3) + 1) hour as endtime
from pts
where status = 0 and user_id = 1 and
      date(time) = date('2014-08-23')
group by floor(hour(time) / 3);

计数为零的值存在问题。我不确定这些有多重要。您的查询对数据进行了透视,但您想要的结果并未进行透视。

编辑:

如果你真的需要所有组的时间,你可以这样做:

select n.n as id, user_id, sum(points),
       date('2014-08-23') + interval 3 * n.n hour as starttime,
       date('2014-08-23') + interval 3 * (n.n + 1) hour as endtime
from (select 0 as n union all select 1 union all select 2 union all select 3 union all
      select 4 union all select 5 union all select 6 union all select 7
     ) n left join
     pts
     on n.n = hour(time) div 3
where status = 0 and user_id = 1 and
      date(time) = date('2014-08-23')
group by n.n;

关于mysql - 如何从今天开始每 3 小时对 MySQL 中的数据进行分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25473331/

相关文章:

mySql 函数不返回任何内容

mysql - 通过带有联接或分组依据的 SQL 请求返​​回过去

php - 如何用sql中WHERE子句中的通配符字符替换空变量

mysql - 尝试使用 mysql/regex 重命名行名

mysql - 如何查询一个表,按同一个表中的名称和标题数分组?

mysql - 获取表中键与另一个表不匹配的所有行

sql - Postgres 数据聚合与可变列

mysql - 查找可用副本数

仅在运行脚本文件时未找到 Python 3.4 MySQL 连接器

sql - 有什么方法可以避免此 Oracle 查询中出现联合吗?