现在,我正在使用DATETIME列在SQL Server中存储大量记录,该列使用GETUTCDATE()
来存储当前时间戳。这确保我们始终存储确切的日期,而不必担心诸如“这是我的2:00还是2:00你的时间?”这样的问题。使用UTC可确保我们确切知道何时发生,而不管时区。我可以在SQL Server的时区之间进行转换吗?
但是,我有一个基本上按日期分组这些记录的查询。此查询的简化版本看起来是这样的:
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 |
+------------+--------+
麻烦的是如果我只是扣除固定-5
,那么4月是正确的,但3月不是,但如果我反而减去固定的-6
那么3月是正确的,但4月不是。我真正需要做的是转换到适当的时区,以了解夏令时并可以相应进行调整。我可以用SQL查询来做到这一点吗?我如何编写这个查询?