T-SQL - определите количество конкретных дней между двумя датами на основе продаж

Проблема: учитывая день недели (1, 2, 3, 4, 5, 6, 7), дату начала и дату окончания, вычислите, сколько раз данный день недели появляется между началом и концом даты, не включающие дату, за которую не было продаж.

Контекст:

Таблица "Билет" имеет следующую структуру и пример содержания:

i_ticket_id c_items_total      dt_create_time       dt_close_time
----------------------------------------------------------------------------
1        8.50       '10/1/2012 10:23:00'    '10/1/2012 11:05:05'
2       10.50       '10/1/2012 11:00:00'    '10/1/2012 11:45:05'
3        8.50       '10/2/2012 08:00:00'    '10/2/2012 09:25:05'
4        8.50       '10/4/2012 08:00:00'    '10/4/2012 09:25:05'
5        7.50       '10/5/2012 13:22:23'    '10/5/2012 14:33:27'
.
.
233      6.75       '10/31/2012 23:20:00'   '10/31/2012 23:55:39'

подробности

  1. В течение месяца могут быть или не быть билеты на один или несколько дней. (то есть место было закрыто в тот / те день)

  2. Дни, в которые бизнес закрыт, не являются регулярными. Там нет предсказуемой картины.

Основываясь на получении количества дней недели (воскресенья, понедельники, вторники) между двумя датами SQL, я получил запрос, который возвращает число раз, когда данный день недели происходит между датой начала и датой окончания:

DECLARE @dtStart DATETIME = '10/1/2013 04:00:00'
DECLARE @dtEnd DATETIME = '11/1/2013 03:59:00'
DECLARE @day_number INTEGER = 1
DECLARE @numdays INTEGER

SET @numdays = (SELECT 1 + DATEDIFF(wk, @dtStart, @dtEnd)-
CASE WHEN DATEPART(weekday, @dtStart)  @day_number THEN 1 ELSE 0 END -
CASE WHEN DATEPART(weekday, @dtEnd) <= @day_number THEN 1 ELSE 0 END)

Теперь мне просто нужно отфильтровать это, чтобы любые дни с нулевым долларом не учитывались. Любая помощь, которую вы можете предоставить, чтобы добавить этот фильтр, основанный на содержании таблицы заявок, очень ценится!

1 ответ

Решение

Если я правильно понимаю, вы можете использовать таблицу календаря для подсчета количества дней, в которых день недели равен n, а также между началом и концом и датой продажи билетов, которая, как я полагаю, существует, когда в билетах существует дата и имеет sum(c_items_total) > 0

WITH cal AS 
(
  SELECT cast('2012-01-01' AS DATE) dt, datepart(weekday, '2012-01-01') dow
  UNION ALL      
  SELECT dateadd(day, 1, dt), datepart(weekday, dateadd(day, 1, dt))
  FROM cal
  WHERE dt < getdate()
)

SELECT COUNT(1)
FROM cal
WHERE dow = 5 
  AND dt BETWEEN '2012-04-01' AND '2012-12-31'
  AND EXISTS (
    SELECT 1
    FROM tickets
    WHERE cast(dt_create_time AS DATE) = dt
    GROUP BY cast(dt_create_time AS DATE)
    HAVING sum(c_items_total) > 0
    )
OPTION (MAXRECURSION 0)

SQLFiddle

Другие вопросы по тегам