Communauté francophone de PostgreSQL

La communauté francophone de PostgreSQL

Outils pour utilisateurs

Outils du site


support:trucs_et_astuces:trouver_le_1er_element_disponible_dans_une_liste_de_numeriques

Trouver le 1er élément disponible dans une liste de numériques

On veut parfois trouver le 1er élément disponible dans une liste. C'est souvent le cas quand la clé primaire d'une table est un nombre mais qu'il n'est pas soumis à une séquence.. Ou alors qu'on a des trous dans la séquence et qu'on veut les combler.

Soit la table nombres (a integer, […]), la requête suivante retourne le 1er élément disponible :

EXPLAIN
SELECT (x.a+1) AS id_disponible
FROM nombres x
     LEFT JOIN nombres y
     ON ((x.a + 1) = y.a)
WHERE y.a IS NULL
ORDER BY x.a LIMIT 1;
 
QUERY PLAN
-----------------------------------------------------------------------------------
LIMIT (cost=0.00..1.58 ROWS=1 width=4)
 -> Nested Loop LEFT JOIN (cost=0.00..22.09 ROWS=14 width=4)
    JOIN FILTER: (("outer".a + 1) = "inner".a)
    FILTER: ("inner".a IS NULL)
    -> INDEX Scan USING id_a ON nombres x (cost=0.00..3.15 ROWS=14 width=4
    -> Seq Scan ON nombres y (cost=0.00..1.14 ROWS=14 width=4)
(6 lignes)
 
test2=> SELECT (x.a+1) AS id_disponible 
  FROM nombres x 
    LEFT JOIN nombres y ON ((x.a + 1) = y.a) WHERE y.a IS NULL ORDER BY x.a LIMIT 1;
 
id_disponible
---------------
4
(1 ligne) 

Si vous constatez des lenteurs, il vous faudra créer un index sur a (si ce n'est pas déjà fait, ce dont je doute):

CREATE UNIQUE INDEX id_a ON nombres(a);

Et un index fonctionnel comme suit:

CREATE INDEX id_a_suivant ON nombres ((a+1));

Merci à John Hansen (appeljack) pour cette idée.


Jean-Paul Argudo le 16/09/2006

support/trucs_et_astuces/trouver_le_1er_element_disponible_dans_une_liste_de_numeriques.txt · Dernière modification: 2008/10/15 16:59 de ioguix