Załóżmy, że mamy tabelę o następującej strukturze:
CREATE TABLE case_status( Id INT,
CaseId CHAR(10),
Status CHAR(10)
)
Tabela ma zapamiętywać historyczne zmiany, które zachodziły dla określonych spraw (CaseId). Przyjrzyjmy się takim danym:
INSERT INTO case_status VALUES(1,’CASE_A’,’Open’),
(2,’CASE_B’,’Open’),
(3,’CASE_A’,’Process’),
(4,’CASE_C’,’Open’),
(5,’CASE_A’,’Close’),
(6,’CASE_B’,’Process’)
Widać, że sprawa „CASE_A: została kiedyś otwarta (rekord nr 1), potem była przetwarzana (rekord nr 3), aż wreszcie została zamknięta (rekord nr 5). Jeżeli przeanalizujemy dane, to okaże sie dodatkowo, że CASE_A jest już zamknięta, CASE_B jest w stanie Process, a CASE_C jest póki co tylko otwarta (Open).
Jakie zapytanie może pokazać aktualny stan tych spraw?
Gdyby zadanie miał do zrealizowania człowiek, to popatrzyłby na rekordy z określonym CaseId, zajrzałby na ostatni rekord (z największym Id, a gdybyśmy zapamiętywali tu daty to z najstarszą datą) i z tego rekordu odczytałby stan bieżący rekordu.
W SQL zerealizujesz to następujacym zapytaniem:
SELECT * FROMcase_status cs
WHERE cs.id >= ALL (SELECT id FROM case_status cs2 WHERE cs2.CaseId = cs.CaseId)
Innymi słowy – na temat każdej sprawy wyświetl tylko ten rekord, który jest >= od ostatniego utworzonego dla tej sprawy rekordu.
Zadanie można by zrealizować także za pomocą podzapytania skorelowanego, ale jego wydajność jest o połowę gorsza:
SELECT * FROMcase_status cs
WHERE cs.id = (SELECT max(id) FROM case_status cs2 WHERE cs2.CaseId = cs.CaseId)