Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Gruppierung aller aktiven Benutzer für jede der letzten 8 Wochen

Setup, also sind wir sicher, dass wir über dasselbe sprechen:

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

Mit dieser Logik sollte es in Woche 1 6 aktive Mitarbeiter geben, in Woche 2 7 aktive Mitarbeiter und in Woche 3 wieder zurück auf 6. Ich brauchte ein paar Minuten, um die aktiven Linien auf ein Blatt Papier zu zeichnen, um herauszufinden, wo Ich habe mich bei meiner Abfrage vertan. Versuchen wir es jetzt mit den Beispieldaten, die wir in tempdb eingerichtet haben:

;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;

Und dann aufräumen:

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