web-dev-qa-db-fra.com

Postgresql SELECT si la chaîne contient

J'ai donc dans mon Postgresql:

TAG_TABLE
==========================
id            tag_name       
--------------------------
1             aaa
2             bbb
3             ccc

Pour simplifier mon problème, ce que je veux faire, c'est SELECT 'id' dans TAG_TABLE lorsqu'une chaîne "aaaaaaaa" contient le "tag_name". Donc, idéalement, il ne devrait renvoyer que "1", qui est l'identifiant du nom de balise 'aaa'

Voici ce que je fais jusqu'à présent:

SELECT id FROM TAG_TABLE WHERE 'aaaaaaaaaaa' LIKE '%tag_name%'

Mais évidemment, cela ne fonctionne pas, car postgres pense que '% tag_name%' signifie un motif contenant la sous-chaîne 'tag_name' au lieu de la valeur de données réelle dans cette colonne.

Comment puis-je passer le tag_name au modèle?

77
user2436815

Vous devez utiliser 'tag_name' en dehors des guillemets; puis son interprété comme un champ de l'enregistrement. Concaténer en utilisant '||' avec les pourcentages littéraux:

SELECT id FROM TAG_TABLE WHERE 'aaaaaaaa' LIKE '%' || tag_name || '%';
93
Frans van Buul

Personnellement, je préfère la syntaxe plus simple de l'opérateur ~.

SELECT id FROM TAG_TABLE WHERE 'aaaaaaaa' ~ tag_name;

Il vaut la peine de lire Différence entre LIKE et ~ dans Postgres pour comprendre la différence. `

33
keithhackbarth

Une méthode appropriée pour rechercher une sous-chaîne consiste à utiliser la fonction position à la place de l'expression like, ce qui nécessite d'échapper à %, _ et à un caractère d'échappement (\ par défaut):

SELECT id FROM TAG_TABLE WHERE position(tag_name in 'aaaaaaaaaaa')>0;
13
Tometzky

En plus de la solution avec 'aaaaaaaa' LIKE '%' || tag_name || '%', il existe position (ordre inversé des arguments) et strpos.

SELECT id FROM TAG_TABLE WHERE strpos('aaaaaaaa', tag_name) > 0

Outre ce qui est plus efficace (LIKE semble moins efficace, mais un index peut changer les choses), il existe un problème très mineur avec LIKE: nom_table ne doit bien sûr pas contenir % et surtout _ (caractère unique à caractère unique ), pour ne pas donner de faux positifs.

8
Joop Eggen