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

過去 8 週間ごとの合計アクティブ ユーザーのグループ化

    セットアップ、つまり、同じことについて話していることは確かです:

    USE tempdb;
    GO
    
    CREATE TABLE dbo.users
    (
        [user_id] INT IDENTITY(1,1) PRIMARY KEY,
        hired_date DATE NOT NULL, 
        termination_date DATE
    );
    
    CREATE TABLE dbo.[date table]
    (
        week_start DATE NOT NULL UNIQUE,
        week_end AS CONVERT(DATE, DATEADD(DAY, 6, week_start))
    );
    GO
    
    SET NOCOUNT ON;
    GO
    
    INSERT dbo.[date table](week_start) VALUES
        ('20110806'),
        ('20110813'),
        ('20110820');
    
    INSERT dbo.users(hired_date, termination_date) VALUES
        ('20110101', NULL), -- long-time, active
        ('20110101', '20110807'), -- long-time, fired in week 1
        ('20110807', '20110815'), -- hired week 1, fired week 2
        ('20110816', '20110816'), -- hired week 2, fired week 2
        ('20110807', '20110825'), -- hired week 1, fired week 3
        ('20110806', NULL), -- hired week 1, active
        ('20110807', NULL), -- hired week 1, active
        ('20110813', NULL), -- hired week 2, active
        ('20110821', NULL); -- hired week 3, active
    GO
      

    このロジックでは、第 1 週にアクティブな従業員が 6 人、第 2 週にアクティブな従業員が 7 人、第 3 週にアクティブな従業員が 6 人になるはずです。クエリを間違えました。それでは、tempdb に設定したサンプル データに対してこれを試してみましょう:

    ;WITH last_8_weeks AS
    (
      SELECT TOP (8) week_start, week_end
        FROM dbo.[date table]
        WHERE week_start >= DATEADD(WEEK, -9, CURRENT_TIMESTAMP)
        ORDER BY week_start DESC
    )
    SELECT d.week_end, COUNT(u.user_id)
      FROM last_8_weeks AS d
      LEFT OUTER JOIN dbo.users AS u
      ON u.hired_date <= d.week_end 
      AND COALESCE(u.termination_date, DATEADD(DAY, 1, d.week_end)) >= d.week_start
      GROUP BY d.week_end
      ORDER BY d.week_end;
      

    そしてクリーンアップ:

    GO
    DROP TABLE dbo.[date table], dbo.users;
      

    1. 複数の行を1つのMySQL結合に結合します

    2. 複雑な種類のフィールド文字列-数値-文字列

    3. 例を使用してSQLで連結する方法について学ぶ

    4. 複数の列にわたる一意の値の制約