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.
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
:
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.
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
1
est dans le tableau de droitetrue
, même si la valeur 4
ne figure pas dans le tableau de droite.4
) ne figure dans le tableau de droite; elle renvoie donc false
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.