现在,我在 SQL Server 中使用 DATETIME 列存储了许多记录,该列使用GETUTCDATE()
. 这样可以确保我们始终存储准确的日期,而不必担心诸如“这是我的时间是 2:00 还是你的时间是 2:00?”之类的问题。使用 UTC 可确保我们准确地知道它何时发生,而不管时区如何。
但是,我有一个查询,基本上按日期对这些记录进行分组。此查询的简化版本如下所示:
SELECT [created], SUM([amount]) AS [amount]
FROM (
SELECT [amount], LEFT(CONVERT(VARCHAR, [created], 120), 10) AS [created]
FROM (
SELECT [amount], DATEADD(HOUR, -5, [created]) AS [created]
FROM [sales]
WHERE [organization] = 1
) AS s
) AS s
GROUP BY [created]
ORDER BY [created] ASC
显然,这个查询远非理想——我在这里的全部原因是询问如何改进它。首先,它确实(在大多数情况下)实现了我在这里寻找的目标——它有按日期分组的东西,其他值也相应地聚合在一起。但它没有完成的是正确处理夏令时。
我住在威斯康星州麦迪逊市,我们是中部时间,所以在 3 月到 11 月之间我们是 UTC-5,否则我们是 UTC-6。这就是为什么您将-5
那里的代码中的 视为使其正常工作的快速技巧。
问题是,如果我运行这个查询,并且有记录落在夏令时转换的两侧,它可能会错误地对事物进行分组。例如,如果表看起来像这样:
+----+--------+---------------------+
| id | amount | created |
+----+--------+---------------------+
| 1 | 100.00 | 2010-04-02 06:00:00 |
| 2 | 50.00 | 2010-04-02 04:30:00 |
| 3 | 75.00 | 2010-04-02 03:00:00 |
| 4 | 150.00 | 2010-03-02 07:00:00 |
| 5 | 25.00 | 2010-03-02 05:30:00 |
| 6 | 50.00 | 2010-03-02 04:00:00 |
+----+--------+---------------------+
我的查询将返回:
+------------+--------+
| created | amount |
+------------+--------+
| 2010-03-01 | 50.00 |
| 2010-03-02 | 175.00 |
| 2010-04-01 | 125.00 |
| 2010-04-02 | 100.00 |
+------------+--------+
然而,理想情况下它应该返回这个:
+------------+--------+
| created | amount |
+------------+--------+
| 2010-03-01 | 75.00 |
| 2010-03-02 | 150.00 |
| 2010-04-01 | 125.00 |
| 2010-04-02 | 100.00 |
+------------+--------+
问题是,如果我只减去一个 fixed -5
,那么 April 是正确的,但 March 不是,但是如果我减去一个 fixed -6
,那么 March 是正确的,但 April 不是。我真正需要做的是以了解夏令时并可以相应调整的方式转换到适当的时区。我可以用 SQL 查询来做到这一点吗?如何编写此查询?