Jak pobrać aktualną wersję rekordu z tabeli historycznych zmian

29-paź-2011

 

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 * FROM
case_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 * FROM
case_status cs
WHERE cs.id = (SELECT max(id) FROM case_status cs2 WHERE cs2.CaseId = cs.CaseId)

Komentarze są wyłączone

Autor: Rafał Kraik