-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

为使这成为可能而输入的额外两个日期将是开始日期 (2013-01-14) 和今天的日期 (2013-03-25)。

每个范围应从原始到期日到下一个到期日的前一天。

任何建议将不胜感激。


更新

这是我到目前为止所尝试的:

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

但这不起作用。

我假设我需要添加一条起始日期为 Anchor 成员的记录。

好的,它现在返回带有上面修改后的代码的数据。

我现在遇到的问题是结果集不限于来自 Anchor 的 AgreementID,我收到一个错误:

Msg 530, Level 16, State 1, Line 1 语句终止。在语句完成之前,最大递归 100 已用完。

4

2 回答 2

2

您的错误是您的语句达到默认递归限制 100 的结果。这可以通过使用MAXRECURSION查询提示来更改。要使用未声明限制的提示,您的语句将如下所示:

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

警告:对递归没有限制时要非常小心。此限制用于短路无限递归循环。根据数据的外观,您的查询可能很容易产生其他问题。我建议逐渐增加您MAXRECURSION的 100 以上以找到合适的上限。在将此代码投入生产之前一定要对此进行测试。

于 2013-03-25T15:45:03.970 回答
1

在 CTE 中可能有一种更优雅的方法,但这是我的解决方案。

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

结果

| 项目 | 截止日期 | 日期 | 约会 | 金额 |
-------------------------------------------------- -------------------------------------------------- ----------------------
| 108 | 2013 年 2 月 1 日 00:00:00+0000 | 2013 年 1 月 14 日 00:00:00+0000 | 2013 年 2 月 25 日 00:00:00+0000 | 60 |
| 108 | 2013 年 2 月 26 日 00:00:00+0000 | 2013 年 2 月 26 日 00:00:00+0000 | 2013 年 2 月 28 日 00:00:00+0000 | 60 |
| 108 | 2013 年 3 月 1 日 00:00:00+0000 | 2013 年 3 月 1 日 00:00:00+0000 | 2013 年 3 月 14 日 00:00:00+0000 | 60 |
| 108 | 2013 年 3 月 15 日 00:00:00+0000 | 2013 年 3 月 15 日 00:00:00+0000 | 2013 年 3 月 25 日 00:00:00+0000 | 60 |

查看演示

于 2013-03-25T15:30:15.110 回答