web-dev-qa-db-fra.com

Vérifier si la valeur existe dans le tableau Postgres

J'ai besoin d'un moyen de tester si une valeur existe dans un tableau donné. Jusqu'à présent, j'ai trouvé quelque chose comme ça

select '{1,2,3}'::int[] @> (ARRAY[]::int[] || value_variable::int)

mais je continue à penser qu'il devrait y avoir un moyen plus simple de procéder, je ne peux tout simplement pas le voir.

Edit: Je viens de me rendre compte que je pourrais le faire

select '{1,2,3}'::int[] @> ARRAY[value_variable::int]

C'est beaucoup mieux et je crois que cela suffira, mais si vous avez d'autres moyens de le faire, partagez-le. 

129
Mike Starov

Plus simple avec la construction ANY }:

SELECT value_variable = ANY ('{1,2,3}'::int[])

L'opérande de droite de ANY (entre parenthèses) peut être un set (résultat d'une sous-requête, par exemple) } _ ou un tableau . Il y a plusieurs façons de l'utiliser:

Important différence: Opérateurs de tableau (<@, @> et al.) } S'attendre tableau types comme opérandes et support GIN ou index Gist dans la distribution standard de PostgreSQL , alors que la construction ANY attend un type element comme opérande gauche et ne prend pas en charge ces index. Exemple:

Rien de cela ne fonctionne pour les éléments NULL. Pour tester NULL:

236
Erwin Brandstetter

Faites attention au piège dans lequel je suis tombé: lorsqu’il vérifie si une valeur n’est pas présente dans un tableau, vous ne devriez pas faire: 

SELECT value_variable != ANY('{1,2,3}'::int[])

mais utiliser 

SELECT value_variable != ALL('{1,2,3}'::int[])

au lieu.

66
murison

mais si vous avez d'autres moyens de le faire, partagez-le. 

Vous pouvez comparer deux tableaux. Si l'une des valeurs du tableau de gauche chevauche les valeurs du tableau de droite, elle renvoie true. C'est un peu bidon, mais ça marche.

SELECT '{1}'   && '{1,2,3}'::int[];  -- true
SELECT '{1,4}' && '{1,2,3}'::int[];  -- true
SELECT '{4}'   && '{1,2,3}'::int[];  -- false
  • Dans la première et la deuxième requête, la valeur 1 est dans le tableau de droite
  • Notez que la deuxième requête est true, même si la valeur 4 ne figure pas dans le tableau de droite.
  • Pour la troisième requête, aucune valeur dans le tableau de gauche (c'est-à-dire, 4) ne figure dans le tableau de droite; elle renvoie donc false
18
vol7ron

Lors de la recherche de l'existence d'un élément dans un tableau, une conversion correcte est nécessaire pour transmettre l'analyseur SQL de postgres. Voici un exemple de requête utilisant un tableau contient un opérateur dans la clause join:

Pour plus de simplicité, je ne liste que la partie pertinente:

table1 other_name text[]; -- is an array of text

La jointure partie de SQL montré

from table1 t1 join table2 t2 on t1.other_name::text[] @> ARRAY[t2.panel::text]

Ce qui suit fonctionne aussi

on t2.panel = ANY(t1.other_name)

Je suppose que le transtypage supplémentaire est nécessaire car l'analyse ne doit pas extraire la définition de la table pour déterminer le type exact de la colonne. D'autres s'il vous plaît commenter à ce sujet.

0
Kemin Zhou