PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Faire correspondre des modèles entre plusieurs colonnes

Jusqu'à présent, les réponses ne répondent pas à votre question :

Cela ne fait pratiquement aucune différence si vous utilisez LIKE ou = tant que vous correspondez à la chaîne entière (et qu'il n'y a pas de caractère générique dans votre chaîne). Pour rendre la recherche floue, vous devez remplacer partie du modèle, pas seulement en y ajoutant.

Par exemple, pour faire correspondre les 7 derniers caractères (au lieu des 8) de la subcolumn :

SELECT *
FROM   maintable m
WHERE  left(maincolumn, 8) LIKE 
       ( '%' || left((SELECT subcolumn FROM subtable WHERE subid = 2), 7));

J'utilise le plus simple left() (introduit avec Postgres 9.1).
Vous could simplifiez ceci en :

SELECT *
FROM   maintable m
WHERE  left(maincolumn, 7) =
       (SELECT left(subcolumn,7) FROM subtable WHERE subid = 2);

Mais vous ne le feriez pas si vous utilisiez l'index spécial que je mentionne plus bas, car les expressions dans les index fonctionnels doivent correspondre précisément pour être utiles.

Vous pourriez être intéressé par l'extension pg_tgrm .

Dans PostgreSQL 9.1, exécutez une fois par base de données :

CREATE EXTENSION pg_tgrm;

Deux raisons :

  • Il fournit l'opérateur de similarité % . Avec lui, vous pouvez créer une recherche intelligente de similarité :

    --SELECT show_limit();
    SELECT set_limit(0.5); -- adjust similarity limit for % operator
    
    SELECT *
    FROM maintable m
    WHERE left(maincolumn, 8) %
          (SELECT subcolumn FROM subtable WHERE subid = 2);
    
  • Il fournit support d'index pour les deux LIKE et %

    Si les performances en lecture sont plus importantes que les performances en écriture, je vous suggère de créer un fonctionnel Index GIN ou GiST comme ceci :

    CREATE INDEX maintable_maincol_tgrm_idx ON maintable
    USING gist (left(maincolumn, 8) gist_trgm_ops);
    

    Cet index prend en charge l'une ou l'autre requête. Sachez que cela entraîne un certain coût pour les opérations d'écriture. dans cette réponse connexe .