Dans une table PostgreSQL où les activités sont regroupées en types A et B, de telle sorte que les activités B suivent toujours les activités A, les utilisateurs recherchent une solution pour extraire la dernière activité A et l'activité B suivante pour chaque utilisateur. Alors que la fonction lead() semblait au départ comme une approche prometteuse, elle s'est avérée inefficace.
Malheureusement, PostgreSQL ne prend actuellement pas en charge les fonctions de fenêtre conditionnelles. La clause FILTER, qui pourrait fournir un filtrage conditionnel pour les fonctions de fenêtre, n'est disponible que pour les fonctions d'agrégation.
L'idée clé réside dans l'implication logique de l'énoncé du problème : pour chaque utilisateur, il y a au plus une activité B après une ou plusieurs activités A. Cela suggère une solution utilisant une fonction de fenêtre unique avec les instructions DISTINCT ON et CASE.
SELECT name , CASE WHEN a2 LIKE 'B%' THEN a1 ELSE a2 END AS activity , CASE WHEN a2 LIKE 'B%' THEN a2 END AS next_activity FROM ( SELECT DISTINCT ON (name) name , lead(activity) OVER (PARTITION BY name ORDER BY time DESC) AS a1 , activity AS a2 FROM t WHERE (activity LIKE 'A%' OR activity LIKE 'B%') ORDER BY name, time DESC ) sub;
Pour un petit nombre d'utilisateurs et d'activités, la requête ci-dessus fonctionnera probablement correctement sans un indice. Toutefois, à mesure que le nombre de lignes et d'utilisateurs augmente, des techniques alternatives peuvent s'avérer nécessaires pour optimiser les performances.
Pour les données volumineuses, envisagez d'utiliser une approche plus personnalisée :
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!