Подсчет количества вхождений по часам в SQL

#sql #sql-server #tsql

#sql #sql-server #tsql

Вопрос:

Я пробовал искать, но, похоже, ответа нет. Возможно, я неправильно гуглю, поэтому прошу прощения, но в основном для таблицы мне нужно подсчитать количество строк, которые имеют логтип успеха, и сгруппировать их по часам за определенный день … например, 1/27.

Пока у меня есть это

 SELECT dateadd(hour, datediff(hour, 0, LogTime), 0) as Hour, LogType
  FROM [<production_db_name>].[dbo].[GPExportLog]
  where LogType like 'Success' and (LogTime BETWEEN '2021-01-27' and '2021-01-28')
 

Что приводит к результату, который выглядит следующим образом,

 Hour, LogType

3-24-2021 17:00 Success
3-24-2021 17:00 Success
3-24-2021 17:00 Success
3-24-2021 18:00 Success
 

Однако мне нужно, чтобы это выглядело примерно так,

 hour, count
3-24-2021 17:00, 3
3-24-2021 18:00, 1
 

Комментарии:

1. Какую БД вы используете? Пожалуйста, добавьте соответствующий тег к вашему вопросу

2. извините, Microsoft SQL Server 2014

3. select dateadd(hour, datediff(hour, 0, LogTime), 0) as Hour, count(*) from ... where ... group by 1

Ответ №1:

Только group by ваш вычисляемый Hour столбец?

 SELECT DATEADD(HOUR, DATEDIFF(HOUR, 0, LogTime), 0) AS [Hour], COUNT(*) AS [Count]
FROM GPExportLog
WHERE LogType like 'Success' AND (LogTime BETWEEN '2021-01-27' AND '2021-01-28')
GROUP BY DATEADD(hour, DATEDIFF(HOUR, 0, LogTime), 0);
 

Или cross apply чтобы избежать повторения вычисления

 SELECT X.[Hour], COUNT(*) AS [Count]
FROM GPExportLog
CROSS APPLY (VALUES (DATEADD(HOUR, DATEDIFF(HOUR, 0, LogTime), 0))) AS X ([Hour])
WHERE LogType like 'Success' AND (LogTime BETWEEN '2021-01-27' AND '2021-01-28')
GROUP BY X.[Hour];
 

Комментарии:

1. Мне всегда казалось неправильным использовать datetime подобное, но я не могу придумать ничего лучше, чем DATETIMEFROMPARTS то, что кажется громоздким. Должно быть что-то лучше

2. @Charlieface вы имеете в виду попытку усечения до уровня часа?

3. ДА. Та же проблема с минутами, секундами, чем угодно. Просто кажется неправильным использовать 0 как своего рода DateTime.MinValue , и это не работает datetime2 . У нас есть EOMONTH , почему бы и нет EOHOUR etc?

4. @Charlieface я даже не заметил, что TBH — ответ просто помещает одно и то же вычисление в group by — я на самом деле не заметил, что он сделал.