日付を使用したより良い例を次に示します。日付のテーブルを作成したいとします。 2017 年の毎月 1 行。 @startDate
を作成します。 アンカーと @endDate
として ターミネーターとして。 1 年が必要なので、これらを 12 か月間隔に設定します。次に、再帰は DATEADD
を介して 1 か月を追加します。 関数を @startDate
に WHERE
でターミネータが見つかるまで 句。 12 か月に到達するには 11 回の再帰が必要であることがわかっています...つまり、11 か月 + 開始日です。 MAXRECURSION
を設定すると WHERE
を満たすには 11 が必要なので、11 未満の場合は失敗します。 再帰的な CTE
の句 、それがターミネーターです..
declare @startDate datetime = '20170101' declare @endDate datetime = '20171201' ;WITH Months as ( SELECT @startDate as TheDate --anchor UNION ALL SELECT DATEADD(month, 1, TheDate) --recursive FROM Months WHERE TheDate < @endDate --terminator... i.e. continue until this condition is met ) SELECT * FROM Months OPTION (MAXRECURSION 10) --change this to 11
プレ>クエリには、単純な結合で十分です。
select firstName ,lastName ,orderDate ,productID from customers c inner join orders o on o.customerID = c.id
プレ>ただし、これを奇妙な形式で返そうとしていることがわかりました。これは、使用しているレポート アプリケーションで処理する必要があります。これにより、再帰なしで閉じることができます。
with cte as( select firstName ,lastName ,orderDate ,productID ,dense_rank() over(order by c.id) as RN from customers c inner join orders o on o.customerID = c.id) select distinct firstName ,lastName ,null ,null ,RN from cte union all select '' ,'' ,orderDate ,productID ,RN from cte order by RN, firstName desc
プレ>