2008-12-18 14 views
3

Y at-il une façon élégante de le faire:SELECT WHERE ... des centaines de conditions

SELECT Cols from MyTable WHERE 
zip = 90210 OR 
zip = 23310 OR 
zip = 74245 OR 
zip = 77427 OR 
zip = 18817 OR 
zip = 94566 OR 
zip = 34533 OR 
zip = 96322 OR 
zip = 34566 OR 
zip = 52214 OR 
zip = 73455 OR 
zip = 52675 OR 
zip = 54724 OR 
zip = 98566 OR 
zip = 92344 OR 
zip = 90432 OR 
zip = 91532 OR 
... 

(codes postaux dans ce poste sont fictivement et ne ressemblent en rien aux codes postaux réels vivants ou morts)

Répondre

28

Oui: Essayez cette requête sql.

Select cols from MyTable where zip in (90210, 23310, ... etc.) 
+0

serait encore mieux stocker les ZIPs dans un table et incorpore un select dans la clause IN. – Unsliced

+1

* Même * mieux serait d'utiliser un 'where exists' ou une jointure au lieu de 'in' – annakata

17

Cela dépend de la définition de « élégante » :)

Cependant, avec autant de codes postaux, je pense que vous pouvez les gérer dans le DB aussi.

Comment décidez-vous quels codes postaux correspondent?

Vous pouvez mettre les codes postaux dans un tableau de leur propre et faire

SELECT cols FROM MyTable, ZipTable WHERE MyTable.zip = ZipTable.zip 
+0

Je suis d'accord.Ce type de requête est généralement un signe qu'il vous manque une table ou une colonne, ou vous essayez de faire ce que les bases de données sont là pour: joindre des choses. –

10

Ou une combinaison des deux, une requête imbriquée:

SELECT cols FROM MyTable WHERE zip IN 
    (SELECT zip FROM ZipTable WHERE condition=true) 
+0

En MySQL IN est moins efficace que EXISTS, donc (si MySQL est utilisé) il vaudrait mieux écrire: SELECT cols FROM MyTable M OERE existe (SELECT 1 FROM ZipTable Z O M. M.ZIP = Z.ZIP et condition = true) – Abgan

3

j'utiliser quelque chose comme:

  • start transaction;
  • create temporary table if not exists ZIPS(ZIP integer) storage=memory;
  • insert into ZIPS (ZIP) VALUES(...)
  • select COLS from MYTABLE M, ZIPS Z where Z.ZIP = M.ZIP
  • drop table ZIPS (ou tronquer ou faire ce que vous voulez)
  • soit commit ou rollback

Dans chaque API db, vous devriez avoir une certaine variation de fonction executemany, qui peut appeler insert into TABLE(COLUMNS) VALUES avec plusieurs rangées de valeurs et être plus rapide que répéter une seule insertion. Et vous pouvez envelopper une telle séquence d'appel dans une fonction, pour la réutiliser facilement, car une table temporaire avec une colonne INT est souvent utile :-)

De cette façon, vous pouvez éviter un problème avec le problème de longueur de requête SQL maximum (par exemple MySQL) et votre requête est efficace, propre et facile à maintenir ou à étendre.

0

Avec autant d'éléments que vous devriez vraiment créer une table de consultation, surtout si vous avez besoin de les parcourir régulièrement dans d'autres sections du code. Cela encapsulera votre code, ce qui facilitera les modifications s'il est utilisé dans de multiples fonctions et une meilleure lecture de l'esthétique.

Exemple: Lookups table --create et remplir la colonne des valeurs avec votre jeu de codes postaux dans ce cas

SELECT Cols 
FROM MyTable 
WHERE EXISTS (Select * FROM Lookups WHERE MyTable.zip = Lookups.values) 

utilisant REJOIGNEZ

SELECT DISTINCT Cols 
FROM MyTable JOIN 
    Lookups ON MyTable.zip = Lookups.values 
+0

Une simple jointure sur les 2 tables sera plus facile à lire et donnera de meilleures performances dans la plupart des cas. (Oui, la table de recherche est une bonne idée!) – mdahlman