Forum Discussion
sql query to check status change of an item
I have a table dbo.tblPresentationStatus (sql script at the bottom )
I have to select rows where the status change is wrong. Flow should be as this:
Review --> approve --> presentation --> close
From 'Review' the status for a specific presentation ID can change to either 'Approve' or 'Presentation' or 'Close'
From 'Approve' the status for a specific presentation ID can change to either 'Presentation' or 'Close'
From 'Presentation' the status for a specific presentation ID can change to only 'Close'
I want to write query to return Presentations with wrong status flow. So expected output as per records given in sql script at the bottom should be :
PrID | Status1 | Status2 | Status3 | Status 4
103 | REVIEW | PRESENTATION | APPROVE |CLOSE
101 | APPROVE | REVIEW | NULL | NULL
-----------------------------------sql script-------------------------------------------
DROP TABLE IF EXISTS #tblPresentation
CREATE TABLE #tblPresentation
(
PrID int NOT NULL,
PrName nvarchar(100) NULL
)
INSERT INTO #tblPresentation VALUES
(100,'PrA'),
(101,'PrB'),
(102,'PrC'),
(103,'PrD')
DROP TABLE IF EXISTS #tblPresentationStatus
CREATE TABLE #tblPresentationStatus
(
StatusID int NOT NULL,
PrID int NOT NULL,
PrStatus nvarchar(100) NOT NULL,
StatusDate datetime NOT NULL
)
INSERT INTO #tblPresentationStatus VALUES
--PRESENTATION ID 100
(1,100,'REVIEW','2024-01-01 00:00:00.00'),
(2,100,'APPROVE','2024-01-02 00:00:00.00'),
(3,100,'PRESENTATION','2024-01-03 07:00:00.00'),
(4,100,'CLOSE','2024-01-03 10:00:00.00'),
--PRESENTATION ID 101
(5,101,'APPROVE','2024-01-01 00:00:00.00'),
(6,101,'REVIEW','2024-01-03 10:00:00.00'), --wrong status change from 'APPROVE' to back ward status of ' REVIEW ' is not allowed
--PRESENTATION ID 102
(7,102,'REVIEW','2024-01-01 00:00:00.00'),
(8,102,'PRESENTATION','2024-01-02 00:00:00.00'),
(9,102,'CLOSE','2024-01-03 10:00:00.00'),
--PRESENTATION ID 103
(10,103,'REVIEW','2024-01-01 00:00:00.00'),
(11,103,'PRESENTATION','2024-01-02 00:00:00.00'),
(12,103,'APPROVE','2024-01-03 00:00:00.00'), --wrong status change from 'PRESENTATION' to back ward status of ' APPROVE' is not allowed
(13,103,'CLOSE','2024-01-04 00:00:00.00')
1 Reply
- rodgerkongIron Contributor
- Create a table with Table Value Constructor to assign a int value to Status string. The table named SI, Column I is the int value.
- Use CTE create a dataset which contains 2 column calculated from window function. One column contains sequence values partition by PrID which named SN. Another one contains the difference of I between current row and the previous row which named Diff.
- Column SN will be used to construct PIVOT table. Obviously, the row with Diff value negative or zero has issue.
- Filter all PrID that have Diff issue, and PIVOT them by SN will get result.
Here is code
WITH C --CTE table AS ( SELECT PS.*, SI.I , ROW_NUMBER() OVER (PARTITION BY PS.PrID ORDER BY StatusID) AS SN --Will used in PIVOT , SI.I - LAG(SI.I, 1, 0) OVER (PARTITION BY PS.PrID ORDER BY StatusID) AS Diff --Find row has issue FROM (VALUES(1, 'REVIEW'), (2, 'APPROVE'), (3, 'PRESENTATION'), (4, 'CLOSE')) AS SI(I, S) --Assign int value to status INNER JOIN #tblPresentationStatus PS ON PS.PrStatus = SI.S ) SELECT PrID, [1] AS [Status1], [2] AS [Status2], [3] AS [Status3], [4] AS [Status4] FROM ( SELECT PrID, PrStatus, SN FROM C WHERE PrID IN ( SELECT PrID FROM C WHERE Diff<=0 ) --Get PrID that has issue )D PIVOT ( MIN(PrStatus) FOR SN IN ([1],[2],[3],[4]) )PP