CTE_Users
各ユーザーの開始日と終了日を含むすべてのユーザーのリストを提供します。
Calendar
と結合されています 各ユーザーの各日付の行を生成するテーブル。
最後に、メイン テーブル Test
と結合されたままになります Total
を返す 日付ごとに。 ISNULL
データを持たない日付が確実に 0 を返すようにします。
WITHCTE_UsersAS( SELECT Userid ,MIN(startdate) AS StartDate ,MAX(enddate) AS EndDate FROM TEST GROUP BY Userid)SELECT ROW_NUMBER() OVER (ORDER BY CTE_Users.Userid, Calendar.dt) AS ID ,CTE_Users .Userid ,T.Id1 ,Calendar.dt ,ISNULL(T.Total, 0) AS TotalFROM CTE_Users INNER JOIN Calendar ON Calendar.dt>=CTE_Users.StartDate AND Calendar.dt <=CTE_Users.EndDate LEFT JOIN TEST AS T ON T .Userid =CTE_Users.Userid AND T.date1 =Calendar.dtORDER BY CTE_Users.Userid, Calendar.dt;
結果
<プレ>| ID |ユーザー ID | ID1 | dt |合計 ||----|--------|--------|------------|------|| 1 | abc | 1 | 2015-01-13 | 200 || 2 | abc | 2 | 2015-01-14 | 200 || 3 | abc | 3 | 2015-01-15 | 200 || 4 | abc | (ヌル) | 2015-01-16 | 0 || 5 | abc | (ヌル) | 2015-01-17 | 0 || 6 | abc | (ヌル) | 2015-01-18 | 0 || 7 | abc | 4 | 2015-01-19 | 200 || 8 | abc | 5 | 2015-01-20 | 200 || 9 | abc | (ヌル) | 2015-01-21 | 0 || 10 | abc | (ヌル) | 2015-01-22 | 0 || 11 | abc | 6 | 2015-01-23 | 200 || 12 | abc | 7 | 2015-01-24 | 200 || 13 |デフ | (ヌル) | 2015-02-10 | 0 || 14 |デフ | (ヌル) | 2015-02-11 | 0 || 15 |デフ | 8 | 2015-02-12 | 200 || 16 |デフ | 9 | 2015-02-13 | 200 || 17 |デフ | (ヌル) | 2015-02-14 | 0 || 18 |デフ | 10 | 2015-02-15 | 200 || 19 |デフ | 11 | 2015-02-16 | 200 || 20 |デフ | 12 | 2015-02-17 | 200 || 21 |デフ | 13 | 2015-02-18 | 200 || 22 |デフ | (ヌル) | 2015-02-19 | 0 || 23 |デフ | (ヌル) | 2015-02-20 | 0 |コード>
ID
その場で生成される行番号です。Id1
Test
の元の ID です テーブル。
Calendar
を生成します このようなテーブル:
CREATE TABLE [Calendar]( [dt] [date] NOT NULLCONSTRAINT [PK_Calendar] PRIMARY KEY CLUSTERED ( [dt] ASC));-- 2000-01-01 から 2027-05-18INSERT までの 10K の日付INTO Calendar (dt)SELECT TOP (10000) DATEADD(day, ROW_NUMBER() OVER (ORDER BY s1.[object_id])-1, '2000-01-01') AS dtFROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2OPTION (MAXDOP 1);