Esta es una pregunta teórica, me preguntaba si hay una buena forma de descubrir qué condición coincide en las declaraciones WHERE.
Digamos que tengo una consulta como esta:
SELECT * FROM table WHERE COND1 OR (COND2 AND COND3) OR COND4
¿Hay alguna forma de saber cuál de las condiciones hace que una fila dada coincida (o no coincida)?
Una solución que pensé fue agregar una cláusula CASE, al SELECT, y volver a ejecutar todas las condiciones WHERE para esa fila:
SELECT *, which_cond = CASE .... END CASE ...
CASE
es una posibilidad. Pero más corto para escribir sería IF()
(al less con MySQL):
SELECT *, IF(COND2, 1, 0) AS cond2, IF(COND3, 1, 0) as cond3 ...
y cada cond*
coincide si su valor es 1
.
Por supuesto, no tiene sentido comprobar si COND1
coincide o no. Para todos los resultados que recibe, COND1
era cierto. Entonces IF(COND1, 1, 0)
siempre devolverá 1
(en su ejemplo).
Actualización :
Nuevamente al less para MySQL, descubrí que lo siguiente es suficiente si solo quieres get 1
o 0
como resultado:
SELECT *, COND2 AS cond2, COND3 as cond3 ...
y con respecto a la respuesta de Mark, puede evitar escribir las condiciones dos veces, si usa HAVING
lugar de WHERE
( HAVING
como acceso a alias):
SELECT *, COND2 AS cond2, COND3 as cond3 FROM table HAVING COND1 AND (cond2 OR cond3)
(nota: mayúscula significa la expresión de condición real y minúscula es el nombre de alias)
Actualización 2:
Bueno, no cambia mucho: solo debe verificar las condiciones que están conectadas mediante OR
en su versión actualizada, sería suficiente para verificar si COND2
es verdadero o no. Si es así, entonces COND3
también es verdadero y viceversa.
SELECT *, COND1 AS cond1, COND2 as cond2, COND4 as cond4 FROM table HAVING cond1 OR (cond2 AND COND3) OR cond4
Creo que el punto es claro.
Su método funciona pero requiere que escriba todas las condiciones dos veces, y si son expresiones complicadas que podrían ser molestas de hacer. La duplicación del código también genera errores cuando las condiciones deben ser cambiadas y usted se olvida de actualizar ambos lugares. Sugeriría usar una subselección para evaluar las condiciones y usar alias a partir de ahí:
SELECT *, CASE WHEN Cond1 AND Cond2 THEN 'Foo' ELSE 'Bar' END AS WhichCondition FROM (SELECT *, (...SQL FOR COND1...) AS Cond1, (...SQL FOR COND2...) AS Cond2, (...SQL FOR COND3...) AS Cond3 FROM table) AS T1 WHERE Cond1 AND (Cond2 OR Cond3)
En SQL Server y Oracle podría usar un CTE en lugar de una subconsulta. No hice esto porque también usaste la label MySql.