2010-12-20 3 views
4

J'ai une table MySql, que je veux interroger pour les lignes dans lesquelles paires des colonnes sont dans un ensemble spécifique. Par exemple, supposons que ma table ressemble à ceci:Filtrage SQL par plusieurs colonnes

id | f1 | f2 
-------------  
1 | 'a' | 20 
2 | 'b' | 20 
3 | 'a' | 30 
4 | 'b' | 20 
5 | 'c' | 20 

Maintenant, je veux extraire les lignes dans lesquelles la paire (f1, f2) sont soit ('a', 30) ou ('b' , 20), à savoir les rangées 2,3,4. Je souhaite également le faire en utilisant un filtre de style 'IN', car j'ai peut-être beaucoup de paires à chercher. Si je tente quelque chose comme:

SELECT * FROM my_table WHERE f1 IN ('a','b') AND f2 IN (30, 20)

Je reçois le produit cartésien des valeurs spécifiées pour f1 et f2 dans les clauses IN, à savoir les lignes avec toutes les combinaisons possibles pour « un » f1 = ou « b » , et f2 = 30, 20, donc la ligne 1 est également sélectionnée.

En bref, je suis besoin de quelque chose comme:

SELECT * FROM my_table WHERE (f1,f2) IN (('a',30), ('b',20))

uniquement avec une syntaxe SQL valide :-)

Toutes les idées?

Répondre

4

Cette est syntaxe valide.

Si vous ne l'aimez pas d'autres alternatives sont:

SELECT * FROM my_table 
WHERE (f1, f2) = ('a', 30) 
OR (f1, f2) = ('b', 20) 

Ou en utilisant une jointure:

SELECT * 
FROM my_table T1 
(
    SELECT 'a' AS f1, 30 AS f2 
    UNION ALL 
    SELECT 'b', 20 
) T2 
ON T1.f1 = T2.f1 AND T1.f2 = T2.f2 
+2

LOL, j'avais la syntaxe valide tous al ong. Validé en MySql. Merci! – bavaza

+0

Relançons les enjeux: disons que j'ai un index sur les colonnes (f1, f2). En utilisant la phrase EXPLAIN, je vois que MySql utilise l'index pour une seule comparaison (par exemple (f1, f2) = ('a', 30)), mais pas pour la syntaxe 'IN'. Des pensées? – bavaza

+0

@bavaza: Cela semble être une question intéressante. Je vous recommande de le poster comme une nouvelle question (pas un commentaire) afin qu'il puisse être vu par plus de gens. –

0
SELECT * FROM my_table WHERE (f1= 'a' AND f2=30) OR (f1='b' AND f2=20); 
+0

Et si je veux avoir ET au lieu de OU. – Akhil

0

Une façon grossière mais pratique consiste à utiliser la concaténation de chaîne:

SELECT * 
FROM MyTable 
WHERE CONCAT(f1, '_', f2) IN ('a_30', 'b_20') 
+1

aussi potentiellement dangereux puisque 111 peut signifier {1, 11} ou {11,1} – Ronnis

+0

A droite, j'ai oublié le '_' dans le' CONCAT'. Bien sûr, ni f1 ni f2 ne devraient contenir '_'! – Don