2013-03-25 4 views
-1

В настоящее время хранит график платежей следующим образом:Создать список диапазонов дат из списка дат

Item No | Due Date | Amount Due 
108  | 2013-02-01 | 60.00 
108  | 2013-02-26 | 60.00 
108  | 2013-03-01 | 60.00 
108  | 2013-03-15 | 60.00 

Примечания: разница между датами противоречива, то есть некоторые пункты могут быть недели, двухнедельный или месяцев.

Что в идеале нужно работать, как повторно запросить таблицу выше в следующем формате:

Item No | Due Date | Date From | Date To | Amount Due 
108  | 2013-02-01 | 2013-01-14 | 2013-02-25 | 60.00 
108  | 2013-02-26 | 2013-02-26 | 2013-02-28 | 60.00 
108  | 2013-03-01 | 2013-03-01 | 2013-03-14 | 60.00 
108  | 2013-03-15 | 2013-03-15 | 2013-03-25 | 60.00 

Лишние две даты, чтобы быть пропущена в, чтобы это было возможно будет Start Дата (2013-01-14) и сегодняшняя дата (2013-03-25).

Каждый диапазон должен исходить из первоначальной даты платежа до дня до следующей даты исполнения.

Любой совет будет оценен.


UPDATE

Вот что я пытался до сих пор:

WITH 
    CTE_Repayments(AgreementID, DueDate, AmountDue) 
AS 
    (
    -- Anchor Member Definition 
     SELECT 
      AgreementID, StartDate, CONVERT(DECIMAL(9,2),0.00) 
     FROM 
      Loans AS L 
     WHERE 
      L.AgreementID = 111 
     UNION ALL 
    -- Recursive Member Definition 
     SELECT 
      RB.AgreementID, RB.DueDate, CONVERT(Decimal(9,2),RB.AmountDue) 
     FROM 
      (
       SELECT * 
       FROM RepaymentBreakdown 
       WHERE AgreementID = 111 
      ) AS RB 
     INNER JOIN 
      CTE_Repayments AS R 
      ON RB.AgreementID = R.AgreementID 
    ) 

-- Statement that Executes CTE 
SELECT AgreementID, DueDate, AmountDue 
FROM CTE_Repayments 

Но это не работает.

Я предполагаю, что мне нужно добавить запись с датой начала в качестве члена привязки.

OK Теперь он возвращает данные с измененным кодом выше.

Проблема у меня сейчас является то, что результирующий набор не ограничивается AgreementID от якоря и я получаю сообщение об ошибке:

Msg 530, Level 16, State 1, Line 1 The statement terminated. The maximum recursion 100 has been exhausted before statement completion.

+0

Что делать, если нет предыдущей 'Due Date'? – Kermit

+0

Всегда есть список дат. Как я уже сказал, мы будем проходить в StartDate в качестве первой даты каждый раз. –

+0

Пробовал ли что-нибудь? – Kermit

ответ

1

Там может быть более элегантный способ сделать это внутри КТР, но вот мое решение.

WITH cte (rowNo, itemNo, dueDate, amountDue) AS 
( 
    SELECT ROW_NUMBER() OVER(ORDER BY [Due Date]) rowNo, 
    [Item No], [Due Date], [Amount Due] 
    FROM loans 
) 
SELECT a.itemNo, a.dueDate, 
    CASE WHEN c.dueDate IS NULL THEN '2013-01-14' 
    ELSE a.dueDate END AS dateFrom, 
    CASE WHEN b.dueDate IS NULL THEN '2013-03-25' 
    ELSE DATEADD(day, -1, b.dueDate) END AS dateTo, 
    a.amountDue 
FROM cte AS a 
LEFT JOIN cte AS b ON b.rowNo = a.rowNo + 1 
LEFT JOIN cte AS c ON c.rowNo = a.rowNo - 1 

Результат

| ITEMNO |       DUEDATE |      DATEFROM |       DATETO | AMOUNTDUE | 
---------------------------------------------------------------------------------------------------------------------------- 
| 108 | February, 01 2013 00:00:00+0000 | January, 14 2013 00:00:00+0000 | February, 25 2013 00:00:00+0000 |  60 | 
| 108 | February, 26 2013 00:00:00+0000 | February, 26 2013 00:00:00+0000 | February, 28 2013 00:00:00+0000 |  60 | 
| 108 | March, 01 2013 00:00:00+0000 | March, 01 2013 00:00:00+0000 | March, 14 2013 00:00:00+0000 |  60 | 
| 108 | March, 15 2013 00:00:00+0000 | March, 15 2013 00:00:00+0000 | March, 25 2013 00:00:00+0000 |  60 |

See the demo

+0

Привет Этот код замечательный, спасибо, но я не могу получить одинаковые результаты при работе с моей базой данных. –

+0

Возможно, им также нужен раздел в окне :? 'OVER (PARTITION BY itemNO ORDER BY ...' –

2

Ваша ошибка является результатом вашего заявления ударяя предел рекурсии по умолчанию 100. Это может быть изменено с помощью MAXRECURSION query hint. Чтобы использовать подсказку без ограничения заявленного, ваше заявление будет выглядеть следующим образом:

-- Statement that Executes CTE 
SELECT AgreementID, DueDate, AmountDue 
FROM CTE_Repayments 
OPTION (MAXRECURSION 0) 

Предупреждение: Будьте очень осторожность не используя никаких ограничений на вашей рекурсии. Этот предел установлен для коротких замыканий бесконечных рекурсивных петель. В зависимости от того, как выглядят данные, ваш запрос может легко раскрутиться и создать другие проблемы. Я бы рекомендовал постепенно увеличивать ваш MAXRECURSION выше 100, чтобы найти соответствующий верхний предел. Определенно проверяйте это, прежде чем вводить этот код в производство.

Смежные вопросы