Генерация пропущенных дат + Sql-сервер (SET BASED) - PullRequest
0 голосов
/ 02 ноября 2009

У меня есть следующее

id eventid  startdate enddate

1 1     2009-01-03 2009-01-05
1 2     2009-01-05 2009-01-09
1 3     2009-01-12 2009-01-15

Как сгенерировать недостающие даты, относящиеся к каждому событию?

Edit: Недостающие пробелы должны быть найдены на основе событий вечера. например для Eventid 1 выход должен быть 1/3 / 2009,1 / 4 / 2009,1 / 5/2009 .. для идентификатора типа события 2 это будет 1/5/2009, 1/6/2009 ... to 1 / 9/2009 и т. Д.

Моя задача - найти пропущенные даты между двумя указанными датами.

Вот все, что я сделал до сих пор

declare @tblRegistration table(id int primary key,startdate date,enddate date)
insert into @tblRegistration 
        select 1,'1/1/2009','1/15/2009'
declare @tblEvent table(id int,eventid int primary key,startdate date,enddate date)
insert into @tblEvent 
        select 1,1,'1/3/2009','1/5/2009' union all
        select 1,2,'1/5/2009','1/9/2009' union all
        select 1,3,'1/12/2009','1/15/2009'

;with generateCalender_cte as
(
    select cast((select  startdate from @tblRegistration where id = 1 )as datetime) DateValue
       union all
        select DateValue + 1
        from    generateCalender_cte   
        where   DateValue + 1 <= (select enddate from @tblRegistration where id = 1)
)
select DateValue as missingdates from generateCalender_cte
where DateValue not between '1/3/2009' and '1/5/2009'
and DateValue not between '1/5/2009' and '1/9/2009'
and DateValue not between '1/12/2009'and'1/15/2009'

На самом деле я пытаюсь сделать следующее: я сгенерировал таблицу календарей, и оттуда я пытаюсь выяснить пропущенные даты на основе идентификатора

Идеальный результат будет

eventid                    missingdates

1             2009-01-01 00:00:00.000

1             2009-01-02 00:00:00.000

3             2009-01-10 00:00:00.000

3            2009-01-11 00:00:00.000

а также он должен быть в SET BASED, а даты начала и окончания не должны быть жестко заданы

Спасибо, спасибо!

Ответы [ 2 ]

3 голосов
/ 02 ноября 2009

Следующее использует рекурсивный CTE (SQL Server 2005 +):

WITH dates AS (
     SELECT CAST('2009-01-01' AS DATETIME) 'date'
     UNION ALL
     SELECT DATEADD(dd, 1, t.date) 
       FROM dates t
      WHERE DATEADD(dd, 1, t.date) <= '2009-02-01')
SELECT t.eventid, d.date
  FROM dates d 
  JOIN TABLE t ON d.date BETWEEN t.startdate AND t.enddate

Генерирует даты, используя функцию DATEADD . Его можно изменить, указав дату начала и окончания в качестве параметров. Согласно комментариям KM , это быстрее, чем использовать трюк с таблицей чисел.

1 голос
/ 02 ноября 2009

Как и rexem - я создал функцию, которая содержит похожий CTE, чтобы генерировать любые серии интервалов даты и времени, которые вам нужны. Очень удобно для суммирования данных по интервалам даты и времени, как вы делаете. Более подробный пост и исходный код функции находятся здесь:

Вставить даты в ответ на запрос, где их нет

Как только у вас будет «количество событий по дате» ... вашими пропущенными датами будут те, в которых будет отсчет 0.

...