CTE_Users
дава ни списък с всички потребители с начална и крайна дата за всеки потребител.
Той е обединен с Календар
таблица за генериране на ред за всяка дата за всеки потребител.
Накрая остава свързан с основната таблица Test
за да върнете Общо
за всяка дата. 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 И T.date1 =Calendar.dtORDER BY CTE_Users.Userid, Calendar.dt;
Резултат
<предварителен код>| ID | Потребителско име | ID1 | dt | Общо ||----|--------|--------|------------|-------|| 1 | abc | 1 | 2015-01-13 | 200 || 2 | abc | 2 | 2015-01-14 | 200 || 3 | abc | 3 | 15 януари 2015 | 200 || 4 | abc | (нула) | 16 януари 2015 | 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 | def | (нула) | 2015-02-10 | 0 || 14 | def | (нула) | 2015-02-11 | 0 || 15 | def | 8 | 2015-02-12 | 200 || 16 | def | 9 | 2015-02-13 | 200 || 17 | def | (нула) | 2015-02-14 | 0 || 18 | def | 10 | 2015-02-15 | 200 || 19 | def | 11 | 2015-02-16 | 200 || 20 | def | 12 | 2015-02-17 | 200 || 21 | def | 13 | 2015-02-18 | 200 || 22 | def | (нула) | 2015-02-19 | 0 || 23 | def | (нула) | 20.02.2015 | 0 |
ID
е номер на ред, генериран в движение.Id1
е оригинални идентификатори от теста
маса.
Бих генерирал Календар
таблица като тази:
CREATE TABLE [Calendar]( [dt] [date] NOT NULLCONSTRAINT [PK_Calendar] PRIMARY KEY CLUSTERED ( [dt] ASC));-- 10K дати от 2000-01-01 до 2027-05-18INSERT 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 КАТО s2OPTION (MAXDOP 1);