2013-08-14 1 views
2

J'ai une table PostgreSQL du format suivant:Looping à travers une table PostgreSQL en bash

uid | defaults | settings 
------------------------------- 
abc | ab, bc  |  - 
    |    | 
pqr | pq, ab  |  - 
    |    | 
xyz | xy, pq  |  - 

Je suis en train d'énumérer tous les uids qui contiennent ab dans la colonne defaults. Dans le cas ci-dessus, abc et pqr doivent être répertoriés. Comment puis-je former la requête et le boucler autour de la table pour vérifier chaque ligne dans bash?

Répondre

2

Il ne s'agit pas vraiment de bash mais vous pouvez appeler votre commande de requête en utilisant psql. Vous pouvez essayer ce format:

psql -U username -d database_name -c "SELECT uid FROM table_name WHERE defaults LIKE 'ab, %' OR defaults LIKE '%, ab' 

Ou peut-être simplement

psql -U username -d database_name -c "SELECT uid FROM table_name WHERE defaults LIKE '%ab%' 

-U username est facultative.

+0

Je trouve cela plus simple. La requête retourne ce dont j'ai besoin mais elle retourne aussi 'ab' si' ab' est sous uid – rahuL

+0

J'ai fait une correction sur le premier. ''*, ab'' aurait dû être' '% ab' '. – konsolebox

2

Utilisez awk:

awk -F\| '$2~/ab/{print $1}' file 

Explication:

  • Le -F\| définit le seperator sur le terrain au | caractère
  • Avec $2~/ab/ on filtre les lignes qui contiennent "ab" dans la deuxième colonne .
  • Avec print $1 nous imprimons la première colonne pour les lignes correspondantes.
3

@user000001 already provided the bash part. Et la requête pourrait être:

SELECT uid 
FROM tbl1 
WHERE defaults LIKE '%ab%' 

Mais cela trouverait aussi intrinsèquement peu fiables , puisque ce « fab » ou « ABZ ». Il est également difficile de créer un index rapide.

Envisagez en normalisant votre schéma. Cela signifie que vous auriez une autre table 1: n tbl2 avec des entrées pour les valeurs par défaut individuelles et une clé étrangère à tbl1. Ensuite, votre requête pourrait être:

SELECT uid 
FROM tbl1 t1 
WHERE EXISTS 
    (SELECT 1 
    FROM tbl2 t2 
    WHERE t2.def = 'ab' -- "default" = reserved word in SQL, so I use "def" 
    AND t2.tbl1_uid = t1.uid); 

Ou au moins utiliser un tableau pour defaults. Votre requête serait alors:

SELECT uid 
FROM tbl1 
WHERE 'ab' = ANY (defaults);