Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak mogę dołączyć moje dane do kalendarza, aby uzyskać rekord dla każdego dnia od początku do końca w SQL Server?

Skrzypce SQL

CTE_Users daje nam listę wszystkich użytkowników z datami rozpoczęcia i zakończenia dla każdego użytkownika.

Jest połączony z Calendar tabela, aby wygenerować wiersz dla każdej daty dla każdego użytkownika.

Na koniec pozostaje połączony z główną tabelą Test aby zwrócić Total na każdą datę. ISNULL zapewnia, że ​​te daty, które nie mają danych, zwracają 0.

WITH
CTE_Users
AS
(
    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 Total
FROM
    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.dt
ORDER BY CTE_Users.Userid, Calendar.dt;

Wynik

| ID | Userid |    Id1 |         dt | Total |
|----|--------|--------|------------|-------|
|  1 |    abc |      1 | 2015-01-13 |   200 |
|  2 |    abc |      2 | 2015-01-14 |   200 |
|  3 |    abc |      3 | 2015-01-15 |   200 |
|  4 |    abc | (null) | 2015-01-16 |     0 |
|  5 |    abc | (null) | 2015-01-17 |     0 |
|  6 |    abc | (null) | 2015-01-18 |     0 |
|  7 |    abc |      4 | 2015-01-19 |   200 |
|  8 |    abc |      5 | 2015-01-20 |   200 |
|  9 |    abc | (null) | 2015-01-21 |     0 |
| 10 |    abc | (null) | 2015-01-22 |     0 |
| 11 |    abc |      6 | 2015-01-23 |   200 |
| 12 |    abc |      7 | 2015-01-24 |   200 |
| 13 |    def | (null) | 2015-02-10 |     0 |
| 14 |    def | (null) | 2015-02-11 |     0 |
| 15 |    def |      8 | 2015-02-12 |   200 |
| 16 |    def |      9 | 2015-02-13 |   200 |
| 17 |    def | (null) | 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 | (null) | 2015-02-19 |     0 |
| 23 |    def | (null) | 2015-02-20 |     0 |

ID to numer wiersza generowany w locie.Id1 to oryginalne identyfikatory z Test stół.

Wygenerowałbym Calendar tabela w ten sposób:

CREATE TABLE [Calendar](
    [dt] [date] NOT NULL
CONSTRAINT [PK_Calendar] PRIMARY KEY CLUSTERED 
(
    [dt] ASC
));

-- 10K dates from 2000-01-01 till 2027-05-18
INSERT INTO Calendar (dt)
SELECT TOP (10000)
    DATEADD(day, ROW_NUMBER() OVER (ORDER BY s1.[object_id])-1, '2000-01-01') AS dt
FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2
OPTION (MAXDOP 1);


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kolumny Unii pionowo w SQL

  2. Przykładowe zapytanie dotyczące serwera połączonego z serwerem SQL

  3. Krzyż stosuje się w Linq

  4. Jak aktualizować i zamawiać za pomocą ms sql

  5. Jak połączyć się z bazą danych SQL Server w CodeIgniter?