2014-09-23 4 views
1

У меня есть таблица, где наш продукт регистрирует журнал активности. Продукт начинает работать в 23:00 каждый день и обычно работает один или два часа. Это означает, что, как только партия началась в 23:00, она заканчивается около 1:00 следующего дня.GROUP BY несколько часов

Теперь мне нужно взять статистику о том, сколько сообщений зарегистрировано для каждой партии, но не может определить сценарий, который позволил бы мне достичь этого. До сих пор я следующий код SQL:

SELECT COUNT(*), DATEPART(DAY,registrationtime),DATEPART(HOUR,registrationtime) 
FROM RegistrationMessageLogEntry 
WHERE registrationtime > '2014-09-01 20:00' 
GROUP BY DATEPART(DAY, registrationtime), DATEPART(HOUR,registrationtime) 
ORDER BY DATEPART(DAY, registrationtime), DATEPART(HOUR,registrationtime) 

что приводит следующие

count day hour 
.... 
1189 9 23 
8611 10 0 
2754 10 23 
6462 11 0 
1885 11 23 

И.Э. Я хочу, чтобы номер для 9-го 23:00 был сгруппирован с номером 10-го числа 00:00, 10 23:00 с 11:00:00 и т. Д. Как я могу это сделать?

ответ

2

Вы можете сделать это очень легко. Используйте DATEADD, чтобы добавить час к оригиналу registrationtime. Если вы это сделаете, все registrationtimes будут перемещены в тот же день, и вы можете просто группировать их по дневной части.

Вы также можете сделать это сложнее, используя CASE WHEN, но это излишний взгляд на это простое решение.

0

Мне пришлось сделать что-то подобное несколько дней назад. У меня были фиксированные временные рамки для смены рабочих групп, где один из них мог начинаться один день в 10 вечера и заканчиваться следующим утром в 6 утра.

Что я сделал:

  1. Определение «дата сдвига», который был просто день с нулевой отметкой времени, когда сдвиг начала для каждой записи в таблице. Я смог сделать это, проверив, была ли отметка времени для входа в период с 0:00 до 6:00. В этом случае я взял только дату этого DATEADD(dd, -1, entryDate), которая вернулась в предыдущий день для всех записей между 0am и 6am.
  2. Я также добавил идентификатор для смены. 0 для первого (6 утра до 2 вечера), 1 для второго (с 2 вечера до 10 вечера) и 3 для последнего (от 10 вечера до 6 утра).
  3. Тогда я смог сгруппировать по дате смены и смена идентификаторов.

Пример:

Рассмотрим следующие записи источник:

Timestamp   SomeData 
============================= 
2014-09-01 06:01:00 5 
2014-09-01 14:01:00 6 
2014-09-02 02:00:00 7 

Шаг один расширил таблицу следующим образом:

Timestamp   SomeData ShiftDay 
==================================================== 
2014-09-01 06:01:00 5   2014-09-01 00:00:00 
2014-09-01 14:01:00 6   2014-09-01 00:00:00 
2014-09-02 02:00:00 7   2014-09-01 00:00:00 

Шаг два расширил таблицу следующим образом:

Timestamp   SomeData ShiftDay    ShiftID 
============================================================== 
2014-09-01 06:01:00 5   2014-09-01 00:00:00 0 
2014-09-01 14:01:00 6   2014-09-01 00:00:00 1 
2014-09-02 02:00:00 7   2014-09-01 00:00:00 2 
0

Вы можете написать сазе, как показано ниже

CASE WHEN DATEPART(HOUR,registrationtime) = 23 
    THEN DATEPART(DAY,registrationtime)+1 
END, 
CASE WHEN DATEPART(HOUR,registrationtime) = 23 
    THEN 0 
END 
0

Ниже запрос даст вам то, что вы ожидаете ..

;WITH CTE AS 
(
SELECT COUNT(*) Count, DATEPART(DAY,registrationtime) Day,DATEPART(HOUR,registrationtime) Hour, 
RANK() over (partition by DATEPART(HOUR,registrationtime) order by DATEPART(DAY,registrationtime),DATEPART(HOUR,registrationtime)) Batch_ID 
FROM RegistrationMessageLogEntry 
WHERE registrationtime > '2014-09-01 20:00' 
GROUP BY DATEPART(DAY, registrationtime), DATEPART(HOUR,registrationtime) 
) 
SELECT SUM(COUNT) Count,Batch_ID 
FROM CTE 
GROUP BY Batch_ID 
ORDER BY Batch_ID 
0

Если добавить один час registrationtime, вы сможете группировать по части даты:

GROUP BY 
    CAST(DATEADD(HOUR, 1, registrationtime) AS date) 

Если начальный час должны быть отражены точно на выходе (как 9, 23, 10, 23 а чем в 10, 0, 11, 0), вы можете получить его в качестве MIN(registrationtime) в ЗЕЬЕСТЕ:

SELECT 
    count = COUNT(*), 
    day = DATEPART(DAY, MIN(registrationtime)), 
    hour = DATEPART(HOUR, MIN(registrationtime)) 

Наконец, в случае, если вы не знаете, вы можете ссылаться на столбцы их псевдонимов в ORDER BY:

ORDER BY 
    day, 
    hour 

просто так, что вам не придется повторять выражения.

Смежные вопросы