Salve,
parli di “controllo”, quindi ritengo tu voglia ad esempio una proiezione che ritorni come risultato “le righe” non valide…
con la seguente popolazione
INSERT INTO dbo.t
VALUES ( '0015177', '2014-11-07', 1 ), ( '0015177', '2016-08-30', 1 ), ( '0015177', '2021-05-26', 0 ) -- OK
, ( '0015177M', '2015-09-08', 0 ), ( '0015177M', '2021-05-26', 0 ) -- FAIL
, ( '0000034011', '2018-07-11', 1 ), ( '0000034011', '2018-07-27', 0 ) -- OK
;
avremmo come FAIL la “prima riga” (temporale DESC) della partition ‘0015177M’
parlo di “partition” perche' probabilmente io ragionerei, appunto, per data islands, o partizioni… per ogni partizione ordinderei in base alla colonna temporale DESC assegnandogli un ROW_NUMBER, in modo da sapere che, appunto, ROW_NUMBER == 1 corrisponde all'ultima riga della partizione, e quindi possiamo verificare che StatoDB sia 1/0 in base al valore appunto di ROW_NUMBER
trivialmente:
WITH ctePartition AS (
SELECT t.CodDB, t.DataDecorrenza, t.StatoDb, ROW_NUMBER() OVER (PARTITION BY t.CodDB ORDER BY t.DataDecorrenza DESC) AS rn
FROM dbo.t t
)
WITH ctePartition AS (
SELECT t.CodDB, t.DataDecorrenza, t.StatoDb, ROW_NUMBER() OVER (PARTITION BY t.CodDB ORDER BY t.DataDecorrenza DESC) AS rn
FROM dbo.t t
)
SELECT t.CodDB, t.DataDecorrenza, t.StatoDb
, t.rn
, CASE WHEN t.rn = 1 AND t.StatoDb = 0
OR t.rn >= 0 AND t.StatoDb = 1
THEN 'OK'
ELSE 'FAIL' END AS [checkStatus]
FROM ctePartition t
ORDER BY t.CodDB, t.DataDecorrenza DESC;
— < --------
CodDB DataDecorrenza StatoDb rn checkStatus
---------- ----------------------- ------- -------------------- -----------
0000034011 2018-07-27 00:00:00.000 0 1 OK
0000034011 2018-07-11 00:00:00.000 1 2 OK
0015177 2021-05-26 00:00:00.000 0 1 OK
0015177 2016-08-30 00:00:00.000 1 2 OK
0015177 2014-11-07 00:00:00.000 1 3 OK
0015177M 2021-05-26 00:00:00.000 0 1 OK
0015177M 2015-09-08 00:00:00.000 0 2 FAIL
quindi, possiamo anche ovviamente filtrare relativamente all'espressione per proiettare le “righe errate”:
WITH ctePartition AS (
SELECT t.CodDB, t.DataDecorrenza, t.StatoDb, ROW_NUMBER() OVER (PARTITION BY t.CodDB ORDER BY t.DataDecorrenza DESC) AS rn
FROM dbo.t t
)
SELECT t.CodDB, t.DataDecorrenza, t.StatoDb
, t.rn
, CASE WHEN t.rn = 1 AND t.StatoDb = 0
OR t.rn >= 0 AND t.StatoDb = 1
THEN 'OK'
ELSE 'FAIL' END AS [checkStatus]
FROM ctePartition t
WHERE 1 =
CASE WHEN t.rn = 1 AND t.StatoDb = 0
OR t.rn >= 0 AND t.StatoDb = 1
THEN 0
ELSE 1 END
ORDER BY t.CodDB, t.DataDecorrenza DESC;
–< -----
CodDB DataDecorrenza StatoDb rn checkStatus
---------- ----------------------- ------- -------------------- -----------
0015177M 2015-09-08 00:00:00.000 0 2 FAIL
ma forse non ho ben compreso quanto chiedi…
salutoni romagnoli
–
Andrea