-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

注: 日付の違いには一貫性がありません。つまり、アイテムによっては、数週間、2 週間、または数か月になる場合があります。

私が理想的に取り組む必要があるのは、上記のテーブルを次の形式に再クエリする方法です。

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

これを可能にするために追加する 2 つの日付は、開始日 (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

しかし、これはうまくいきません。

アンカーメンバーとして開始日を持つレコードを追加する必要があると想定しています。

OK、上記の修正されたコードで Data が返されるようになりました。

私が今抱えている問題は、結果セットがアンカーからのAgreementIDに制限されておらず、エラーが発生することです:

メッセージ 530、レベル 16、状態 1、行 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 に答える