web-dev-qa-db-fra.com

PostgreSQL: Comment créer une requête "insensible à la casse"

Est-il possible d'écrire des requêtes insensibles à la casse dans PostgreSQL, E.g. Je veux que les 3 requêtes suivantes retournent le même résultat.

SELECT id FROM groups where name='administrator'

SELECT id FROM groups where name='ADMINISTRATOR'

SELECT id FROM groups where name='Administrator'
277
Jame

Utilisez la fonction LOWER pour convertir les chaînes en minuscules avant de les comparer.

Essaye ça:

SELECT id 
  FROM groups
 WHERE LOWER(name)=LOWER('Administrator')
381
Chandu

en utilisant ILIKE au lieu de LIKE

SELECT id FROM groups WHERE name ILIKE 'Administrator'
176

L'approche la plus courante consiste à mettre en minuscule ou en majuscule la chaîne de recherche et les données. Mais cela pose deux problèmes.

  1. Cela fonctionne en anglais, mais pas dans toutes les langues. (Peut-être même pas dans la plupart des langues.) Toutes les lettres minuscules n'ont pas de lettre majuscule correspondante; toutes les lettres majuscules n'ont pas une lettre minuscule correspondante.
  2. L'utilisation de fonctions telles que lower () et upper () vous donnera une analyse séquentielle. Il ne peut pas utiliser d'index. Sur mon système de test, l'utilisation de lower () prend environ 2000 fois plus de temps qu'une requête pouvant utiliser un index. (Les données de test comportent un peu plus de 100 000 lignes.)

Il existe au moins trois solutions moins fréquemment utilisées qui pourraient être plus efficaces.

  1. Utilisez le module citext , qui imite généralement le comportement d'un type de données insensible à la casse. Une fois ce module chargé, vous pouvez créer un index non sensible à la casse en CREATE INDEX ON groups (name::citext);. (Mais voir ci-dessous.)
  2. Utilisez un classement qui ne respecte pas la casse. Ceci est défini lorsque vous initialisez une base de données. L'utilisation d'un classement ne respectant pas la casse signifie que vous pouvez accepter à peu près n'importe quel format du code client et que vous obtiendrez tout de même des résultats utiles. (Cela signifie également que vous ne pouvez pas faire de requêtes sensibles à la casse. Duh.)
  3. Créer un index fonctionnel. Créez un index minuscule en utilisant CREATE INDEX ON groups (LOWER(name));. Cela fait, vous pouvez tirer parti de l’index avec des requêtes telles que SELECT id FROM groups WHERE LOWER(name) = LOWER('ADMINISTRATOR'); ou SELECT id FROM groups WHERE LOWER(name) = 'administrator';. Vous devez vous rappeler pour pouvoir utiliser INFÉRIEUR (), cependant.

Le module citext ne fournit pas un type de données véritablement insensible à la casse. Au lieu de cela, il se comporte comme si chaque chaîne était minuscule. Autrement dit, il se comporte comme si vous aviez appelé lower() sur chaque chaîne, comme dans le numéro 3 ci-dessus. L'avantage est que les programmeurs n'ont pas à se souvenir des chaînes minuscules. Mais vous devez lire les sections "Comportement de comparaison de chaînes" et "Limitations" dans la documentation avant de décider d'utiliser citext.

112

Vous pouvez utiliser ILIKE. c'est à dire.

SELECT id FROM groups where name ILIKE 'administrator'
91
ADJ

Vous pouvez également consulter le mot clé ILIKE. Cela peut parfois être très utile, même si cela n’est pas conforme au standard SQL. Voir ici pour plus d'informations: http://www.postgresql.org/docs/9.2/static/functions-matching.html

51
Priidu Neemre

Vous pouvez également utiliser des expressions régulières POSIX, comme

SELECT id FROM groups where name ~* 'administrator'

SELECT 'asd' ~* 'AsD' retourne t

24
James Brown

L'utilisation de ~* peut améliorer considérablement les performances, avec les fonctionnalités de INSTR.

SELECT id FROM groups WHERE name ~* 'adm'

retourne les lignes dont le nom contient OR est égal à 'adm'.

4
Robin Goh