2011-10-13 3 views
1

J'ai une requête mySQL quelque peu complexe que j'essaie d'exécuter. J'ai deux paramètres: facility et isEnabled. L'installation peut avoir la valeur "ALL" ou être un ID spécifique. isEnabled peut avoir la valeur "ALL" ou être 0/1.Problème de requête MySQL complexe

Mon problème est que je dois venir avec la logique qui peut gérer les scénarios suivants: 1) Facility = ALL ET isEnabled = ALL 2) Facility = ALL ET isEnabled = valeur 3) Facility = someID ET isEnabled = ALL 4) Facilité = someID ET isEnabled = valeur

le problème est que j'ai plusieurs instructions IF imbriquées:

IF (Facility = 'ALL') THEN 
    IF (isEnabled = 'ALL') THEN 
    SELECT * FROM myTable 
    ELSE 
    SELECT * FROM myTable 
    WHERE isEnabled = value 
    END IF; 
ELSE 
    IF (isEnabled = 'ALL') THEN 
    SELECT * FROM myTable 
    WHERE facility = someID 
    ELSE 
    SELECT * FROM myTable 
    WHERE facility = someID AND isEnabled = value 
    END IF; 
END IF; 

Je voudrais être en mesure de combiner la logique dans la clause WHERE utilisant une déclaration CASE ou Conditionnel (ET/OU) mais j'ai du mal à envelopper la tête ce matin. Actuellement, la requête ne fonctionne pas comme prévu.

Un aperçu serait utile! Merci

+0

Vous pouvez simplement mettre cette logique dans votre 'WHERE' clause et utiliser des parenthèses ... –

Répondre

2

Vous pouvez le faire ...

SELECT 
    * 
FROM 
    myTable 
WHERE 
    1=1 
    AND (facility = someID OR Facility = 'ALL') 
    AND (isEnabled = value OR isEnabled = 'ALL') 

Cependant, cela donne un mauvais plan d'exécution - il essaie de trouver une taille unique, mais chaque combinaison de paramètres peut avoir différents plans en fonction des données , index, etc.

Cela signifie qu'il est préférable de construire la requête dynamique

SELECT 
    * 
FROM 
    myTable 
WHERE 
    1=1 
    AND facility = someID -- Only include this line if : Facility = 'ALL' 
    AND isEnabled = value -- Only include this line if : isEnabled = 'ALL' 

Je sais qu'il peut se sentir sale u Les requêtes dynamiques, mais c'est un bon exemple de quand puis vraiment peut exceller. Je vais trouver un lien spectaculaire pour vous maintenant. (Il y a beaucoup à lire, mais il est très peine d'apprendre de)

Lien: Dynamic Search

+0

+1 de la mauvaise performance d'exécution re the the 'OU' Motif optionnel – StuartLC

+0

Je suppose que je devrais mentionner que cela provient d'une procédure stockée et que j'ai réduit les champs. Il y a 187 colonnes qui sont réellement dans l'instruction SELECT (pas SELECT * FROM) .. en lisant sur ce lien et il semblait que cela suggérait que la requête entière soit construite dans le SP. La transmission de 187 champs du code nécessitera des modifications majeures de la programmation. Vous ne savez pas si cela sera gérable. Sauf si je vois quelque chose de mal? – Encryption

+0

C'est un jeu de trades-and-soldes. Si vous avez une condition * parfois * dans la clause WHERE, la construction dynamique de cette manière peut générer des avantages significatifs. En termes de clause SELECT, les avantages sont beaucoup plus petits, bien que vous puissiez toujours effectuer une optimisation en fonction des paramètres que vous utiliseriez dans la clause WHERE. Si vous avez 187 champs consultables, et donc 187 entrées de clause WHERE possibles, vous regardez 187 paramètres d'une façon ou d'une autre, n'est-ce pas? – MatBailie