Как исправить порядок таблицы SQL по DateTimeOffset со смещением, иногда отсутствующим - PullRequest
0 голосов
/ 31 марта 2020

У меня есть грязная таблица, заполненная событиями, которые иногда получают DateTime, а в других местах присваивается DateTimeOffset, назначенный полю Date, аналогично этому (при условии, что вы живете достаточно далеко за пределами долготы Divided Kingdom):

DECLARE @MY_LOG TABLE ([MOMENT] DATETIMEOFFSET, [PAYLOAD] NVARCHAR(200));

INSERT INTO @MY_LOG ([MOMENT],[PAYLOAD]) VALUES (GETDATE(),'first entry')
WAITFOR DELAY '00:00:00.100';
INSERT INTO @MY_LOG ([MOMENT],[PAYLOAD]) VALUES (SYSDATETIMEOFFSET(),'second entry')
WAITFOR DELAY '00:00:00.100';
INSERT INTO @MY_LOG ([MOMENT],[PAYLOAD]) VALUES (GETDATE(),'third entry')
WAITFOR DELAY '00:00:00.100';
INSERT INTO @MY_LOG ([MOMENT],[PAYLOAD]) VALUES (SYSDATETIMEOFFSET(),'forth entry')

SELECT [MOMENT],[PAYLOAD] FROM @MY_LOG ORDER BY [MOMENT] ASC;

Результатом последнего выбора будет следующий пример:

2020-03-31 02:39:10.6779279 +02:00  second entry
2020-03-31 02:39:10.8809259 +02:00  forth entry
2020-03-31 02:39:10.5730000 +00:00  first entry
2020-03-31 02:39:10.7770000 +00:00  third entry

Я попытался исправить это с помощью SWITCHOFFSET, который добавляет отсутствующее смещение, но также компенсирует его:

SELECT [MOMENT],
       [PAYLOAD],
       CASE WHEN DATEPART(tz,[MOMENT])=0 THEN SWITCHOFFSET(MOMENT, '+02:00') ELSE MOMENT END AS FIXED 
FROM @MY_LOG ORDER BY FIXED ASC;

Результат:

2020-03-31 02:39:10.6779279 +02:00  second entry 2020-03-31 02:39:10.6779279 +02:00
2020-03-31 02:39:10.8809259 +02:00  forth entry  2020-03-31 02:39:10.8809259 +02:00
2020-03-31 02:39:10.5730000 +00:00  first entry  2020-03-31 04:39:10.5730000 +02:00
2020-03-31 02:39:10.7770000 +00:00  third entry  2020-03-31 04:39:10.7770000 +02:00

Мне также может понадобиться учесть моменты переключения, как в Этот вопрос , но сейчас я ищу не разрушительное (только для чтения) решение упорядочить строки по дате

1 Ответ

0 голосов
/ 31 марта 2020

Нашел ответ прямо перед публикацией: уберите смещение, преобразовав в datetime2(7):

SELECT [MOMENT],
       [PAYLOAD],
       CONVERT(datetime2(7),[MOMENT]) AS FIXED
FROM @MY_LOG ORDER BY FIXED ASC;

результат - правильно упорядоченная таблица (за исключением двух часов в год, когда переход на летнее время переключается).

2020-03-31 03:04:04.3630000 +00:00  first entry  2020-03-31 03:04:04.3630000
2020-03-31 03:04:04.4689375 +02:00  second entry 2020-03-31 03:04:04.4689375
2020-03-31 03:04:04.5670000 +00:00  third entry  2020-03-31 03:04:04.5670000
2020-03-31 03:04:04.6709404 +02:00  forth entry  2020-03-31 03:04:04.6709404
...