PostgreSQL
La base de données la plus sophistiquée au monde.

Ouverture de session

Navigation

Contactez-nous

Administration du site :
"equipe chez postgresqlfr point org"

Contact presse :
"fr chez postgresql point org"

Contact association :
"bureau chez postgresqlfr point org"

Questions PostgreSQL :
 IRC :
  serveur irc.freenode.net
  canal #postgresqlfr

Recherche

Accéder aux archives

« Octobre 2008  
Lun Mar Mer Jeu Ven Sam Dim
  2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31  

Syndication

Flux XML

Sondage

Quelle est la version de PostgreSQL la plus répandue sur vos serveurs ?
8.3
10%
8.2
42%
8.1
40%
8.0
2%
7.4
6%
7.3 ou antérieure
0%
Nombre de votes: 48

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

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

Par Jean-Paul Argudo le 16/09/2006 - 11:49

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 élement 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.

© PostgreSQLFr, tous droits réservés.
Site déclaré à la CNIL sous le numéro 1074678, conformément à la Loi en vigueur.