sql >> データベース >  >> RDS >> Sqlserver

SQL Server:再帰 CTE を書き換えて、ビューのオプション maxrecursion を置き換えます

    タリーを使用できます。これはセットベースのソリューションであり、反復回数が増えると再帰よりも優れたパフォーマンスを発揮します - ビューでサポートされています。

    アプローチは次のとおりです。

    select t.objectid, t.amount, dateadd(day, x.n, t.begindate) as dt
    from (
        select row_number() over (order by (select null)) - 1
        from (values(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) a(n)
        cross join (values(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(n)
        cross join (values(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(n)
    ) x(n)
    inner join tabledatarange t
        on dateadd(day, x.n, t.begindate) <= case 
            when enddate <= convert(date, getdate()) then enddate
            else convert(date, getdate())
        end
    

    集計は 0 から 999 までのすべての数値を生成します (cross join を追加することで簡単に拡張できます) s)。これを使用して元のテーブルの行を「乗算」し、日付範囲を生成します。

    終了日を扱う部分を書き直そうとしました。将来の日付が必要ないことは理解しています。それが on の条件です

    このサンプル データの場合:

    ObjectId | Amount | beginDate  | endDate   
    -------: | -----: | :--------- | :---------
           1 |    500 | 2020-12-28 | null      
           2 |     35 | 2019-09-26 | 2019-10-01
           3 |    200 | 2020-05-28 | 2020-06-02
    

    クエリは次を返します:

    objectid | amount | dt        
    -------: | -----: | :---------
           1 |    500 | 2020-12-28
           1 |    500 | 2020-12-29
           1 |    500 | 2020-12-30
           1 |    500 | 2020-12-31
           2 |     35 | 2019-09-26
           2 |     35 | 2019-09-27
           2 |     35 | 2019-09-28
           2 |     35 | 2019-09-29
           2 |     35 | 2019-09-30
           2 |     35 | 2019-10-01
           3 |    200 | 2020-05-28
           3 |    200 | 2020-05-29
           3 |    200 | 2020-05-30
           3 |    200 | 2020-05-31
           3 |    200 | 2020-06-01
           3 |    200 | 2020-06-02
    

    DB Fiddle のデモ



    1. JSONタイプ内の配列要素のクエリ

    2. mysqli挿入-ただし、重複していない場合のみ

    3. Oracleの間隔関数

    4. バインディング変数とそれらを指定するSQLクエリ