【问题标题】:MySQL query to group results by hour of day, taking into account daylight savingsMySQL查询按一天中的小时对结果进行分组,考虑到夏令时
【发布时间】:2013-03-26 18:03:30
【问题描述】:

我有一个使用类似这样的 sql 查询的报告:

SELECT HOUR(somedatetime) AS hour, COUNT(*) AS count
FROM table
GROUP BY HOUR(surveyenddatetime)

我在这里简化了它,省略了可以将结果限制在给定时间段内的 where 子句。它可以很好地获取在所选时间段内输入的按一天中的小时分组的总记录。

但是,它有一个致命的缺陷。当所选择的时间段包括与运行报告的用户不相同的“时区”的记录,例如来自夏令时的记录和夏令时的记录,它不起作用。所有记录都以 GMT/UTC 格式存储在日期时间字段中,并通过 Web 前端在 php 中转换为本地时间。但是这个查询会在任何事情发生之前运行,php 无法知道每个小时的总数的原始日期是什么。

有没有一种方法可以解决这个查询,以仅使用 MySQL 查询将夏令时考虑在内,还是我必须做一些更复杂的事情?

【问题讨论】:

    标签: mysql group-by dst


    【解决方案1】:

    CONVERT_TZ:

    SELECT 
        HOUR(CONVERT_TZ(`somedatetime`, 'UTC', 'Europe/Amsterdam')) AS `hour`, 
        COUNT(*) AS `count`
    FROM table
    GROUP BY `hour`
    

    将用户的时区代替“欧洲/阿姆斯特丹”传递到查询中。

    另请参阅:https://dev.mysql.com/doc/refman/5.5/en/mysql-tzinfo-to-sql.html(您可能需要使用时区数据初始化 MySQL。)

    【讨论】:

    • 这是不对的。记录需要返回他们自己时区的小时,而不是用户。因此,如果我从 3 月 1 日格林威治标准时间 09:00 开始有一条记录,从 4 月 4 日开始在英国夏令时 09:00 有另一条记录,它们都出现在“9”的总数中。
    • 我以为你说记录是以UTC格式存储的?所以他们会在进入数据库的途中被转换?
    • 是的,为了保持一致性,它们都以 UTC 格式存储。但是对于报告,我需要夏令时的记录来返回他们当地时间的小时(即+1)。
    • 我不确定您所说的“夏令时记录”是什么意思——它们要么是 UTC,要么是本地时区。如果所有内容都存储在 UTC 中,那么它来自哪个时区并不重要。即用户在美国东部时间晚上 10 点登录,该时间将转换为 UTC 时间戳,然后由另一个时区的用户从日志中检索为该用户的本地时间。
    • 其实我可能没看懂你的回答。当我第一次看时,您似乎误解了我的问题。现在我怀疑它可能是相反的方式。我会试试你的解决方案,看看它是否有效...... :)
    猜你喜欢
    • 2019-05-26
    • 2014-01-25
    • 2011-08-14
    • 2017-12-26
    • 2020-03-01
    • 2013-09-22
    • 1970-01-01
    • 2023-03-26
    • 2013-01-15
    相关资源
    最近更新 更多