Рекурсивное CTE возвращает значение вне диапазона - PullRequest
0 голосов
/ 20 сентября 2018

При поиске метода для создания диапазонов дат я столкнулся с проблемой следующего запроса:

DECLARE @StartDate DateTime = '2000-01-01 01:00';
DECLARE @EndDate DateTime = '2020-01-01 00:00';

with Dates as (
  select
  @StartDate fromDate
  UNION ALL
  (Select
     fromDate = dateadd(day, 1, @EndDate)
   from
     Dates
   where
     fromDate >= @StartDate AND
     fromDate < @EndDate ))

Select * from Dates
OPTION (MAXRECURSION 0);

Следующий запрос возвращает две строки, одна из которых выходит за пределы диапазона,

fromDate
-----------------------
2000-01-01 01:00:00.000
2020-01-02 00:00:00.000

Мне известно, что существует способ решить эту проблему, изменив вторую половину запроса, например:

Select * from Dates Where fromDate <= @EndDate 

У меня есть следующие вопросы:

  • что не так с запросом как есть?
  • Почему этот запрос возвращает два значения, одно из которых лежит за пределами указанного диапазона?

Это использует Microsoft SQL Server 2008 R2

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Простой ответ для # 1 / # 2: вы выбираете DATEADD (день, 1, @endDate) - который, по определению, на 1 день больше вашего диапазона дат.

Реальноеответ: Чтобы получить желаемый результат, измените:

(Select
    fromDate = dateadd(day, 1, @EndDate)

На:

(Select
    fromDate = dateadd(day, 1, fromDate)
0 голосов
/ 21 сентября 2018

Потому что ваш Recursive CTE добавляет один день из fromDate

Select
     fromDate = dateadd(day, 1, @EndDate)

, но ваш фильтр условий fromDate

where
     fromDate >= @StartDate AND
     fromDate < @EndDate ))

Если вы хотите сделать календарьТаблица Recursive CTE.

Вы можете попробовать это.

with Dates as (
  select @StartDate fromDate,@EndDate endDate
  UNION ALL
  Select
     fromDate = dateadd(day, 1, fromDate),endDate
   from
     Dates
   where
      dateadd(day, 1, fromDate) <= @EndDate 
)
Select * from Dates
OPTION (MAXRECURSION 0);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...