2017-01-18 4 views
0

ввод - это основной диапазон дат, который хранится в значениях столбцов myTbl.StartDate и myTbl.EndDate. для заданного постоянного значения в качестве разделителя, мне нужно вычислить дату начала диапазонов поддиапазонов, полученных от деления диапазона основных дат на диапазоны поддиапазонов с постоянной длиной значения. примеров являются лучшими объяснениями: для основного диапазона дат между «2017-1-1» до «2017-1-22» и const_val выхода = 6 является:введите дату начала дат-диапазона от заданного основного диапазона дат в sql-сервере

2017-1-1 
    2017-1-7 (1 + 6) 
    2017-1-13 (7 + 6) 
    2017-1-19 (13 + 6) 

его заметно, что пользователь SQL не администратор (я не могу использовать системные таблицы)

+0

Прежде всего, было бы замечательно, если бы вы могли пометить используемые вами dbms (даже если вы упомянули, что это SQL Server). Но другой вопрос: есть ли у вас какая-то таблица календаря? DimDate или что-то вроде этого? И еще одно: нужно ли быть в одном запросе или вы могли бы использовать цикл? – Tyron78

+0

Пожалуйста, покажите ожидаемый результат. – McNets

+0

Ожидаемый результат указан выше: 2017-01-01, 2017-01-07, 2017-01-13, 2017-01-19 – Tyron78

ответ

1

Вы можете использовать рекурсивные CTE, чтобы сделать это:

DECLARE @startDate DATE = '20170101' , 
    @endDate DATE = '20170122' , 
    @Const_val INT = 6; 
WITH cte 
      AS (SELECT @startDate AS DateVal 
       UNION ALL 
       SELECT DATEADD(DAY, @Const_val, cte.DateVal) 
       FROM  cte 
       WHERE DATEADD(DAY, @Const_val, cte.DateVal) <= @endDate 
      ) 
    SELECT * 
    FROM cte; 

Производит:

DateVal 
========== 
2017-01-01 
2017-01-07 
2017-01-13 
2017-01-19 

Первая часть КТР получает первую дату:

SELECT @startDate AS DateVal 

Тогда это добавляет 6 дней с UNION ALL до тех пор, пока не будет выполнено условие WHERE.

+0

Выглядит почти так же, как мое решение. :-) – Tyron78

+1

не совсем, если вы отметите мой комментарий;) – Tanner

1

Вы можете попробовать следующее:

DECLARE @StartDate DATE = CONVERT(date, '2017-01-01'); 
DECLARE @EndDate DATE = CONVERT(date, '2017-01-22'); 
DECLARE @FixDateDiff int = 6; 


WITH cte AS (
    SELECT @StartDate AS MyDate 
    UNION ALL 
    SELECT DATEADD(d, 1, MyDate) 
    FROM cte 
    WHERE DATEADD(d, 1, MyDate) <= CONVERT(date, @EndDate) 
) 
SELECT MyDate 
    FROM cte 
    WHERE DATEDIFF(d, @StartDate, MyDate)%@FixDateDiff = 0 

Однако вместо фиксированных дат я присвоенных переменных, просто замените переменные с StartDate и столбца EndDate и расширить cte accordi ngly.

+1

вы можете просто использовать значение '@FixDateDiff' в' DATEADD', а не в предложение WHERE за пределами cte для более простого решения – Tanner

+0

Да, вы правы. Моя вина. ;-) – Tyron78