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'
подробности
В течение месяца могут быть или не быть билеты на один или несколько дней. (то есть место было закрыто в тот / те день)
Дни, в которые бизнес закрыт, не являются регулярными. Там нет предсказуемой картины.
Основываясь на получении количества дней недели (воскресенья, понедельники, вторники) между двумя датами 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)