Сортировка / группировка SQL по дням недели и часам дня - PullRequest
6 голосов
/ 21 августа 2011

У меня есть таблица SQL Server 2005, которая содержит записи с полем даты UTC / GMT. Мне нужно, чтобы записи GROUPed BY и ORDERed были «день недели» и «час дня». Даёт 7 * 24 = 168 групп. Вывод будет выглядеть так:

Sun 12am
Sun  1am
Sun  2am
.... etc
Mon 12am
Mon  1am
.... etc
.... etc
Sat 10pm
Sat 11pm

Все работает нормально, пока я не попытаюсь преобразовать вещи в местный часовой пояс. Выполнение преобразования внутри SQL:

SELECT MIN(Key),MIN(SavedOn), 
FROM MyTable 
GROUP BY (DatePart(WEEKDAY, SavedOn)*24.0) + DatePart(HOUR, SavedOn) - (5.0/24.0)
ORDER BY (DatePart(WEEKDAY, SavedOn)*24.0) + DatePart(HOUR, SavedOn) - (5.0/24.0)

Или делать преобразование в моем собственном коде ПОСЛЕ сортировки / получения записей в UTC:

SELECT MIN(Key),MIN(SavedOn), 
FROM MyTable 
GROUP BY (DatePart(WEEKDAY, SavedOn)*24.0) + DatePart(HOUR, SavedOn)  
ORDER BY (DatePart(WEEKDAY, SavedOn)*24.0) + DatePart(HOUR, SavedOn) 

(my own math here)

В любом случае ... 5 записей появятся "не в порядке". Записи конца недели (сб PM) появляются в начале недели ... не в конце ... где они принадлежат.

Есть идеи, что я делаю не так?

Ответы [ 2 ]

4 голосов
/ 21 августа 2011

Математика с плавающей точкой неточна. Умножение на 24.0 приводит к появлению ошибок границ.

Вместо добавления чисел

GROUP BY (DatePart(WEEKDAY, SavedOn)*24.0) + DatePart(HOUR, SavedOn)  

вместо сортировки по двум полям:

GROUP BY DatePart(WEEKDAY, SavedOn), DatePart(HOUR, SavedOn) 
1 голос
/ 21 августа 2011

Вот что я бы сделал.Я не уверен, что полностью понимаю, что вы пытаетесь:

SELECT DatePart(WEEKDAY, SavedOn), DatePart(HOUR, SavedOn) , min(key)
FROM MyTable 
GROUP BY DatePart(WEEKDAY, SavedOn), DatePart(HOUR, SavedOn)
ORDER BY 1, 2

Если ваш подход к конвертации заключается в добавлении 5 часов, делайте это каждый раз, когда вы видите SavedOn, например:

SELECT DatePart(WEEKDAY, SavedOn+5.0/24.0), DatePart(HOUR, SavedOn+5.0/24.0) , min(key)
FROM MyTable 
GROUP BY DatePart(WEEKDAY, SavedOn+5.0/24.0, DatePart(HOUR, SavedOn+5.0/24.0)
ORDER BY 1, 2
...