Różnica pomiędzy datami

0

Myślę nad takim problemem - jest tabela z identyfikatorami (np. zamówień) i datami (np. zamówienia). Chcę wyznaczyć różnicę pomiędzy tymi datami - ID, Data, Różnica.
Na pewno przyda się tutaj DATEDIFF. Problem rozwiązałem przykładowo tak:

SELECT ID, Data, ABS(DATEDIFF(day, Data, LAG(Data) OVER (ORDER BY Data))) AS Różnica

Funkcja LAG działa tutaj świetnie, i problem został rozwiązany szybko i przyjemnie. Aczkolwiek wiem, że można również zagnieździć całego SELECT'a w miejscu LAG który nam to wyliczy, i nie mam pomysłu jak to zrobić. Wiem że nie ma sensu sobie utrudniać, ale na prawdę chciałbym poznać również alternatywne rozwiązanie.

Jakieś sugestie jak to można zrobić?

1

LAG i LEAD bardziej pomagaja uniknąć join-a pomiędzy jedna tabelą, podzapytaniem to będzie tak

select 
    (select top 1 data from t sq where sq.data < q.data order by data desc)
data_poprzednia
from t q

Zamiast ćwiczyć takie podzapytanie, napisz to za pomocą joina-a, więcej wyniesiesz z takiej nauki

UPDATE:

sam siebie poprawie, bo moje zapytanie nie jest poprawne, nie sprawdzi sie dla takiego zestawu

data
2019-01-01
2019-01-02
2019-01-02

Porównanie:

data LAG podzapytanie
2019-01-01 null null
2019-01-02 2019-01-01 2019-01-01
2019-01-02 2019-01-02 2019-01-01

Także jak pisałem wcześniej, zrob join-a ;)

1

@Panczo: Tak to jest jak się nie ma ID :)

with x(id,data) as
(
values (1, '2019-01-01'::date), (2, '2019-01-02'), (3, '2019-01-02'), (4, '2019-01-03'), (5, '2019-01-04')
)
select 
	*, 
	lag(data) over(order by data),
	(select data from x y where y.data<=x.data and y.id<x.id order by data desc limit 1)
from x 

Działa dobrze :)

0

Zapytanie faktycznie nie działa, a te powyżej muszę ogarnąć bo nie ta składnia co Microsoft. Nie do końca wiem gdzie mam tutaj robić joina, ale i tak czy siak chcę rozgryźć jak to zagnieździć.

1

join może wygladać tak:

with rpt as (
select
     row_number() over (order by data lp
     ,*
from
    tabela
)
select
     c.data
     p.data [zamiast lag]
from
   rpt c
   left join rpt p on c.lp-1 = p.lp

Zapytanie @Marcin.Miga jest zgodne z tsql, jedynie sposób generowania danych with x jest tylko dla posgresa

0

Zapytanie @Marcin.Miga działa, ale nie do końca. Zakładając że poprawnie je przerobiłem.

SELECT q.ID, q.Data, 
(
	SELECT TOP 1 q1.Data
        FROM Tabela q1 
        WHERE q.Data >= q1.Data AND q.ID > q1.ID AND q1.Data IS NOT NULL 
        ORDER BY q1.Data DESC
)
FROM Tabela q
WHERE q.Data IS NOT NULL
ORDER BY q.ID ASC

Zapytanie wydaje się działać perfekcyjnie, poza ostatnim wynikiem.
Wynik
Powinno być 2013, dalej powtórzył 1998.

1

Zapytanie @Marcin.Miga działa, ale nie do końca. Zakładając że poprawnie je przerobiłem.

Przerobiłes poprawnie, to jest to co pisałem w komentarzu pod jego postem, sort po id, nie odpowiada kolejności dat, dlatego to się nie sprawdza i pozostaje join albo LAG

0

Tyle że kolejność id w tym przypadku się zgadza.

1

No nie, 2 ostatnie rekordy:

order by id

id data
831 2013-06-03
832 2013-06-01

order by data

id data
832 2013-06-01
831 2013-06-03
0

Faktycznie jeden jest na odwrót. Czyli trzeba to połączyć a przed tym zrobić sobie nowy klucz.
W takim razie problem wydaje się być rozwiązany. Bardzo dziękuję za pomoc.

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