Een "selecteer binnen een select" wordt vaker "subselect" of "subquery" genoemd. In uw specifieke geval is het een gecorreleerde subquery . LATERAL
joins (nieuw in postgres 9.3) kunnen gecorreleerde subquery's grotendeels vervangen door flexibelere oplossingen:
Ik denk dat je hier ook niet nodig hebt.
Voor uw eerste geval deze zoekopdracht is echter waarschijnlijk sneller en eenvoudiger:
SELECT date, max(value) OVER (PARTITION BY grp) AS value
FROM (
SELECT *, count(value) OVER (ORDER BY date) AS grp
FROM test_fill_null
) sub;
count()
telt alleen niet-null-waarden, dus grp
wordt verhoogd met elke niet-null value
, waardoor groepen naar wens gevormd worden. Het is triviaal om de één te kiezen niet-null value
per grp
in de buitenste SELECT
.
Voor uw tweede geval , ik neem aan dat de initiële volgorde van rijen wordt bepaald door (id1, id2, tms)
zoals aangegeven door een van uw vragen.
SELECT id1, id2, tms
, count(step) OVER (ORDER BY id1, id2, tms) AS group_id
FROM (
SELECT *, CASE WHEN lag(tms, 1, '-infinity') OVER (PARTITION BY id1 ORDER BY id2, tms)
< tms - interval '5 min'
THEN true END AS step
FROM table0
) sub
ORDER BY id1, id2, tms;
Aanpassen aan uw werkelijke bestelling. Een van deze kan het dekken:
PARTITION BY id1 ORDER BY id2 -- ignore tms
PARTITION BY id1 ORDER BY tms -- ignore id2
SQL Fiddle met een uitgebreid voorbeeld.
Gerelateerd: