现在我在SQL Server中存储了许多记录,其中DATETIME列使用GETUTCDATE()
存储当前时间戳。这样可以确保我们始终存储确切的日期,而无需担心“我的时间是2点还是2点你的时间?”这样的问题。使用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 |
+------------+--------+
麻烦的是,如果我只是减去一个固定的-5
,那么四月是正确的但三月不是,但如果我改为固定-6
,那么三月是正确的,但四月不是。我真正需要做的是以一种了解夏令时的方式转换到适当的时区,并可以相应地进行调整。我可以用SQL查询吗?我该如何撰写此查询?
答案 0 :(得分:2)
当前的日期/时间功能都不支持DST。
使用辅助日历表可能是您最好的选择:
您可以按日期存储UTCOffset,并在您的select语句中引用它
答案 1 :(得分:1)
如果您能够将数据存储在datetimeoffset字段而不是datetime中 这可能有所帮助。
http://msdn.microsoft.com/en-us/library/bb630289.aspx
此数据类型和corepsonding函数是sql server 2008的新功能。