To accomplish this, I would first create an aggregation table like thisCREATE TABLE dbo.MyProcessStatus ( Process_ID INT NOT NULL, Status VARCHAR(11) NOT NULL )CREATE UNIQUE NONCLUSTERED INDEX IX_ProcessID ON dbo.MyProcessStatus (Process_ID) WITH FILLFACTOR = 95
To populate this table for the first time, I then would run this piece of code-- What date is today?DECLARE @Now DATETIMESET @Now = DATEDIFF(DAY, '19000101', GETDATE())-- Add all ProcessID statusINSERT dbo.MyProcessStatus ( Process_ID, Status )SELECT Process_ID, CASE WHEN Complete = 1 THEN 'Complete' WHEN Late = 1 THEN 'Late' WHEN Endangered = 1 THEN 'Endangered' WHEN Started = 1 THEN 'Started' WHEN Started = 0 THEN 'Not started' ELSE '<unknown>' ENDFROM ( SELECT ap.Process_ID, MIN(CASE WHEN ap.Completion_Date IS NULL THEN 0 ELSE 1 END) AS Complete, MAX(CASE WHEN ap.Estimated_Completion_Date < @Now THEN 1 ELSE 0 END) AS Late, MAX(CASE WHEN ap.Estimated_Completion_Date >= @Now ap.Estimated_Completion_Date < DATEADD(DAY, 14, @Now) THEN 1 ELSE 0 END) AS Endangered, MAX(CASE WHEN ap.Completion_Date IS NULL THEN 0 ELSE 1 END) AS Started, FROM Activities_Processes AS ap GROUP BY ap.Process_ID ) AS d
At this point I would create a trigger to keep track of all changes in the Activities_Processes table.The trigger can look something like thisCREATE TRIGGER dbo.trgProcessStatus ON Activities_ProcessesFOR UPDATE, INSERT, DELETEASSET NOCOUNT ON-- Remove all old instances of ProcessID statusDELETE mpsFROM dbo.MyProcessStatus AS mpsINNER JOIN ( SELECT Process_ID FROM inserted UNION ALL SELECT Process_ID FROM deleted ) AS x ON x.Process_ID = mps.Process_ID-- What date is today?DECLARE @Now DATETIMESET @Now = DATEDIFF(DAY, '19000101', GETDATE())-- Add new instance of ProcessID statusINSERT dbo.MyProcessStatus ( Process_ID, Status )SELECT Process_ID, CASE WHEN Complete = 1 THEN 'Complete' WHEN Late = 1 THEN 'Late' WHEN Endangered = 1 THEN 'Endangered' WHEN Started = 1 THEN 'Started' WHEN Started = 0 THEN 'Not started' ELSE '<unknown>' ENDFROM ( SELECT ap.Process_ID, MIN(CASE WHEN ap.Completion_Date IS NULL THEN 0 ELSE 1 END) AS Complete, MAX(CASE WHEN ap.Estimated_Completion_Date < @Now THEN 1 ELSE 0 END) AS Late, MAX(CASE WHEN ap.Estimated_Completion_Date >= @Now AND ap.Estimated_Completion_Date < DATEADD(DAY, 14, @Now) THEN 1 ELSE 0 END) AS Endangered, MAX(CASE WHEN ap.Completion_Date IS NULL THEN 0 ELSE 1 END) AS Started, FROM Activities_Processes AS ap INNER JOIN inserted as i ON i.Process_ID = ap.Process_ID GROUP BY ap.Process_ID ) AS d
And to get your result as originally wanted, I would use this querySELECT Status, COUNT(*) AS Num_ProcessesFROM dbo.MyProcessStatus GROUP BY Status
E 12°55'05.25"N 56°04'39.16"