SQL Запрос на подсчет ежедневных пропусков дней - PullRequest
1 голос
/ 07 февраля 2020

Этот запрос подсчитывает количество бутылок, которые мы производим за месяц, и группирует их по дням. Если в этот день не будет произведено ни одной бутылки, то она пропускается с выхода, а не возвращает 0 произведенных бутылок. Как я могу вернуться с отметкой времени дня, если бутылок нет? Я слышал, что для этого нужно использовать таблицу календаря.

SELECT CONVERT(datetime,CAST(t_stamp AS DATE)), COUNT(bottles) AS 'Good Bottles'
FROM bottles
WHERE t_stamp
    BETWEEN "any date"
    AND "any date"
GROUP BY CAST(t_stamp AS DATE)
ORDER BY CAST(t_stamp AS DATE) ASC

Токовый выход:

Aug 12, 2019 12:00 am..................4302
Aug 13, 2019 12:00 am..................2302
Aug 17, 2019 12:00 am..................1302
Aug 18, 2019 12:00 am..................4302

Желаемый выход:

Aug 12, 2019 12:00 am..................4302
Aug 13, 2019 12:00 am..................2302
Aug 14, 2019 12:00 am..................0
Aug 15, 2019 12:00 am..................0
Aug 16, 2019 12:00 am..................0
Aug 17, 2019 12:00 am..................1302
Aug 18, 2019 12:00 am..................4302

1 Ответ

1 голос
/ 07 февраля 2020

Вам нужно сгенерировать дни. Довольно простой метод использует рекурсивный CTE:

WITH dates as (
      SELECT CONVERT(date, "any date1") as dte
      UNION ALL
      SELECT DATEADD(day, 1, dte)
      FROM dates
      WHERE dte < "any date2"
     )
SELECT d.dte, COUNT(bottles) AS GoodBottles
FROM dates d LEFT JOIN
     bottles b
     ON CAST(t_stamp as DATE) = d.dte
GROUP BY d.dte
ORDER BY d.dte ASC;

Примечания:

  • Если у вас есть календарь или таблица подсчета, используйте его вместо этого.
  • Если количество дат превышает 100, нужно добавить OPTION (MAXRECURSION 0).
  • COUNT(bottles) выглядит подозрительно. Вы действительно намереваетесь SUM(bottles)?
  • Преобразование столбца в date, а затем в datetime также подозрительно. Неясно, почему вы хотите datetime для первого столбца.
...