Un "sélection dans une sélection" est plus communément appelé "sous-sélection" ou "sous-requête" Dans votre cas particulier, il s'agit d'une sous-requête corrélée . LATERAL
les jointures (nouveau dans postgres 9.3) peuvent largement remplacer les sous-requêtes corrélées par des solutions plus flexibles :
Je ne pense pas que vous ayez besoin de l'un ou l'autre ici.
Pour votre premier cas cette requête est probablement plus rapide et plus simple :
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()
ne compte que les valeurs non nulles, donc grp
est incrémenté avec chaque value
non nulle , formant ainsi des groupes comme souhaité. C'est trivial de choisir un value
non nulle par grp
dans le SELECT
externe .
Pour votre second cas , je suppose que l'ordre initial des lignes est déterminé par (id1, id2, tms)
comme indiqué par l'une de vos requêtes.
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;
Adaptez-vous à votre commande réelle. L'un d'entre eux pourrait le couvrir :
PARTITION BY id1 ORDER BY id2 -- ignore tms
PARTITION BY id1 ORDER BY tms -- ignore id2
SQL Fiddle avec un exemple étendu.
Connexe :