Прямо сейчас я храню несколько записей в 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
Очевидно, что этот запрос далеко не идеален - единственная причина, по которой я здесь, состоит в том, чтобы спросить, как его улучшить.Во-первых, он (по большей части) выполняет цель, которую я здесь ищу, - это вещи, сгруппированные по датам, и другие значения, сгруппированные соответственно.Но то, чего он не достигает, - это корректное обращение с летним временем.
Я живу в Мэдисоне, штат Висконсин, и у нас центральное время, поэтому с марта по ноябрь мы 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-запроса?Как мне написать этот запрос?