2010-07-07 96 views
4

现在,我正在使用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查询来做到这一点吗?我如何编写这个查询?

回答

相关问题