Funkcje analityczne - data wprowadzenia wartości

0

Mam do rozwiązania problem. Postaram się go opisać możliwie dokładnie, ale nie wiem czy mi się uda, gdyż sam nie wiem o co dokładnie chodzi :( Mianowicie:

Tabela zawiera klientów. klient opisany jest przez jakieś ID. Klient może zmieniać swoją aktywność (nie ważne z jakiej na jaką), a każda zmiana aktywności jest opisana poprzez START_DTE oraz END_DTE. W pewnym momencie klient umiera i podana jest data kiedy zmarł (ale aktywności mogą się zmieniać nawet po jego śmierci). W tabeli bedzie to wygladalo mniej wiecej tak:

ID START_DTE END_DTE ZGON
ID1 1-01-2009 1-08-2009 null
ID1 2-08-2009 10-10-2009 null
ID1 11-10-2009 4-12-2009 null
ID1 5-12-2013 2-02-2014 1-12-2013
ID1 3-02-2014 30-11-2014 1-12-2013
ID1 1-12-2014 null 1-12-2013

Moim zadaniem jest znaleźć DATĘ WPROWADZENIA daty zgonu do tabeli (nie datę zgonu, tylko datę jej wprowadzenia). Czyli patrząc na tabele powyżej, jeśli wartość w polu ZGON pojawia się po raz pierwszy, tzn, że START_DTE w tym wierszu to właśnie data wprowadzenia daty zgonu do tabeli.

Początkowo zrobiłem to tak, że odfiltrowałem

WHERE ZGON IS NOT NULL

i wybrałem MIN(START_DTE) AS DATA_WPROWADZENIA

, ale ta metoda jest zbyt prosta i muszę skorzystać z czegos bardziej wyszukanego, żeby się nauczyć. Dostałem wskazówki żeby zastosować funkcje analityczne OVER PRECEDING FOLLOWING, ale średnio widzę jak można by to zrobić tą metodą. Podobno można jeszcze JOINem ale tu już w ogóle nie mam pomysłu. 

Jeśli chodzi o sposób pierwszy, to wymyśliłem jedynie coś takiego: zastosować funkcję PRECEDING, która doda mi jedną kolumnę z przesunięciem daty zgonu w dół. Wtedy w wierszu z moją datą wprowadzenia powstanie różnica i dodając warunek
```sql
 WHERE PRZESUNIECIE <> ZGON

wcyiągnę tylko ten jedyny wiersz który mnie interesuje (tabela poniżej). Niestety Kolumny utworzonej w wyniku funkcji analitycznej nie moge używać w warunku WHERE, a wrzucenie całego zapytania do podzapytania lub CTE wymieszało mi wszystkie wartości (nie mam pojęcia dlaczego).

ID</th> START_DTE</th> END_DTE</th> ZGON</th> PRZESUNIECIE</th> </tr> </thead> ID1</td> 1-01-2009</td> 1-08-2009</td> null</td> null</td> </tr> ID1</td> 2-08-2009</td> 10-10-2009</td> null</td> null</td> </tr> ID1</td> 11-10-2009</td> 4-12-2009</td> null</td> null</td> </tr> ID1</td> 5-12-2013</td> 2-02-2014</td> 1-12-2013</td> null</td> </tr> ID1</td> 3-02-2014</td> 30-11-2014</td> 1-12-2013</td> 1-12-2013</td> </tr> ID1</td> 1-12-2014</td> null</td> 1-12-2013</td> 1-12-2013</td> </tr> </tbody> </table>

Być może moje wnioskowanie dotyczące zastosowania funkcji analitycznej jest błędne, więc proszę o wskazówki jak rozwiązać problem. Ewentualnie jak to zrobić JOINem.

Pozdrawiam!

0

Nie wiem do końca co dla Twojego przełożonego/nauczyciela znaczy za proste bo według mnie najprostsze działające rozwiązanie jest najlepsze.
Jeżeli chodzi o Joina:

use SampleDB
go
with forum4programmers as (
Select t1.id, t1.start_dte 
from dbo.table1 as t1
inner join
dbo.table1 as t2
on t1.id=t2.Id and t1.zgon is not null
)
Select id, min(start_dte) as "I believe I can fly"
from forum4programmers
group by id

Mógłbyś użyć też filtra where zamiast warunku "on" ale w przypadku inner joina to to samo.

Jeżeli chodzi o funkcje okna to np.:


use SampleDB
go
with forum4programmers as (
select id, start_dte, lag(zgon,1,0) over(partition by id order by start_dte) as whatever
from table1
)
Select id,max(start_dte) as "whatsoever"
from forum4programmers
where whatever is null
group by id

Jakby znowu Ci powiedzieli, że za proste to pisz ;-)

1 użytkowników online, w tym zalogowanych: 0, gości: 1