PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment étiqueter les groupes dans postgresql lorsque l'appartenance au groupe dépend de la ligne précédente ?

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 :