postgresql
Fönsterfunktioner
Sök…
generiskt exempel
Förbereda data:
create table wf_example(i int, t text,ts timestamptz,b boolean);
insert into wf_example select 1,'a','1970.01.01',true;
insert into wf_example select 1,'a','1970.01.01',false;
insert into wf_example select 1,'b','1970.01.01',false;
insert into wf_example select 2,'b','1970.01.01',false;
insert into wf_example select 3,'b','1970.01.01',false;
insert into wf_example select 4,'b','1970.02.01',false;
insert into wf_example select 5,'b','1970.03.01',false;
insert into wf_example select 2,'c','1970.03.01',true;
Löpning:
select *
, dense_rank() over (order by i) dist_by_i
, lag(t) over () prev_t
, nth_value(i, 6) over () nth
, count(true) over (partition by i) num_by_i
, count(true) over () num_all
, ntile(3) over() ntile
from wf_example
;
Resultat:
i | t | ts | b | dist_by_i | prev_t | nth | num_by_i | num_all | ntile
---+---+------------------------+---+-----------+--------+-----+----------+---------+-------
1 | a | 1970-01-01 00:00:00+01 | f | 1 | | 3 | 3 | 8 | 1
1 | a | 1970-01-01 00:00:00+01 | t | 1 | a | 3 | 3 | 8 | 1
1 | b | 1970-01-01 00:00:00+01 | f | 1 | a | 3 | 3 | 8 | 1
2 | c | 1970-03-01 00:00:00+01 | t | 2 | b | 3 | 2 | 8 | 2
2 | b | 1970-01-01 00:00:00+01 | f | 2 | c | 3 | 2 | 8 | 2
3 | b | 1970-01-01 00:00:00+01 | f | 3 | b | 3 | 1 | 8 | 2
4 | b | 1970-02-01 00:00:00+01 | f | 4 | b | 3 | 1 | 8 | 3
5 | b | 1970-03-01 00:00:00+01 | f | 5 | b | 3 | 1 | 8 | 3
(8 rows)
Förklaring:
dist_by_i : dense_rank() over (order by i)
är som ett radnummer per olika värden. Kan användas för antalet distinkta värden på i ( count(DISTINCT i)
inte fungerar). Använd bara det maximala värdet.
prev_t : lag(t) over ()
är ett tidigare värde på t över hela fönstret. tänk på att det är noll för den första raden.
nth : nth_value(i, 6) over ()
är värdet på sjätte rader kolumn i över hela fönstret
num_by_i : count(true) over (partition by i)
är ett antal rader för varje värde på i
num_all : count(true) over ()
är en mängd rader över ett helt fönster
ntile : ntile(3) over()
delar upp hela fönstret till 3 (så mycket som möjligt) lika i mängddelar
kolumnvärden vs täta_rank vs rangordning vs radnummer
här kan du hitta funktionerna.
Kör med tabellen wf_example skapad i föregående exempel:
select i
, dense_rank() over (order by i)
, row_number() over ()
, rank() over (order by i)
from wf_example
Resultatet är:
i | dense_rank | row_number | rank
---+------------+------------+------
1 | 1 | 1 | 1
1 | 1 | 2 | 1
1 | 1 | 3 | 1
2 | 2 | 4 | 4
2 | 2 | 5 | 4
3 | 3 | 6 | 6
4 | 4 | 7 | 7
5 | 5 | 8 | 8
dense_rank beställer VÄRDER av i efter utseende i fönstret.
i=1
visas, så första raden har dense_rank, nästa och tredje i-värdet förändras inte, så det ärdense_rank
visar 1 - FIRST-värde har inte ändrats. fjärde radeni=2
, det är andra värdet på jag träffat, sådense_rank
visar 2, och så för nästa rad. Sedan möter det värdeti=3
på 6: e raden, så det visar 3. Samma för resten två värden på i . Så det sista värdet pådense_rank
är antalet distinkta värden på i .radnummer beställer ROWS när de är listade.
rank För att inte förväxla med
dense_rank
denna funktion ROW NUMBER i- värden. Så det börjar samma sak med tre, men har nästa värde 4, vilket innebär atti=2
(nytt värde) uppfylldes på rad 4. Sammai=3
uppfylldes på rad 6. Et ..