2011-02-02 4 views
8

que tienen esta consulta:¿Cómo difiere el uso de OR en una instrucción MySQL con/sin paréntesis?

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02' 
    AND `status` = 'active' OR `status` = 'past due' 

que no devuelve los resultados correctos. Sin embargo, la adición de paréntesis alrededor de las condiciones o hace que funcione de esta manera:

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02' 
    AND (`status` = 'active' OR `status` = 'past due') 

Mi pregunta es ¿por qué es diferente? Entiendo que eso es considerar la declaración O de manera diferente sin los paréntesis; pero no entiendo cómo es diferente.

No he encontrado ningún documento que haya sido útil en esto. Si hay enlaces por ahí, realmente lo agradecería.

Respuesta

15

Esto se debe a que O tiene operator precedence menor que AND. Siempre que el PP ve una expresión como

A AND B OR C 

la Y se evalúa primero, es decir, es equivalente a

(A AND B) OR C 

Así que si quieres explícitamente

A AND (B OR C) 

lugar, debe poner en el paréntesis

Esto, por cierto, no es específico de SQL. El orden de precedencia de estos operadores es el mismo en todos los lenguajes de programación que conozco (es decir, al menos C, C++, C#, Java y scripts de shell de Unix).

0

En su primera consulta status = 'activa' es condición falsa entonces no evalute siguiente condición de columna de estado (status)

en su segunda consulta

paréntesis() tienen alta prioridad

. Entonces (status = 'activo' O status = 'vencido') condición evaluar primero.

2

en

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02' 
    AND `status` = 'active' OR `status` = 'past due' 

se examinará en primer lugar date_next_payment <= '2011-02-02' AND status = 'active' y luego se hará la respuesta booleano de esta planta o con status = 'past due'

Mientras que en

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02' 
    AND (`status` = 'active' OR `status` = 'past due') 

primera o será hecho y luego Y se hará ... Eso es y esto dará la respuesta diferente

2

El manual de MySQL tiene una página en operator precedence. Muestra que AND tiene una precedencia más alta. Por lo tanto, p1 AND p2 OR p3 se interpreta como (p1 AND p2) OR p3. Una tabla de verdad le convencerá fácilmente de que esto es diferente de p1 AND (p2 OR p3).

3
SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02' 
AND `status` = 'active' OR `status` = 'past due' 

En este ejemplo, obtendrá todos los registros donde sea

a) El date_next_payment es antes del 2 de 2011 FEB y el estado está activo

b) la situación es past_due

Así los registros de fechas_actuales no estarán restringidos por fecha.

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02' 
AND (`status` = 'active' OR `status` = 'past due') 

En este ejemplo, obtendrá todos los registros donde

a) El date_next_payment es antes del 2 Feb 2011

Y

b) El estado puede ser activo o past_due

Los corchetes funcionan como lo hacen en matemática o lógica: las afirmaciones entre corchetes se evalúan primero ... así que imagínese que cada paso tenga lugar como es:

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02' 
AND (`status` = 'active' OR `status` = 'past due') 

Así que un registro se encuentra con un estado de activo ...

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02' 
AND (TRUE OR FALSE) 

Este evalúa entonces, con la condición O ... (verdadero o falso) == TRUE

SELECT * FROM (`users`) WHERE `date_next_payment` <= '2011-02-02' 
AND TRUE 

Y la fecha es 2011-01-01

SELECT * FROM (`users`) WHERE TRUE 
AND TRUE 

Y por último, == verdadero y cierto Cierto

SELECT * FROM (`users`) WHERE TRUE 

Y así, se devuelve el expediente ...

Imaginando la consulta que se ejecutan en los pasos como éste contra cada fila en la base de datos a veces ayuda a entender dónde poner tus paréntesis

0

Es porque cuando no se está utilizando el paréntesis que en realidad diciendo:

`date_next_payment` <= '2011-02-02'  AND `status` = 'active' 
OR 
`status` = 'past due'. 

que significa que cuando status` = 'vencidos' este registro se muestra también. independientemente de pasar las otras condiciones.

Pero cuando usted hace uso de paréntesis, se requieren:

`date_next_payment` <= '2011-02-02' 

Y para pasar una de las otras dos condiciones.

1

No es especial sobre SQL, se trata de lógica booleana. Su primera afirmación es:

A y B o C

Esto significa que si cualquier c es verdadera, se obtiene la fila.

En una Y (B o C)

que presentamos lo mejor sólo las filas donde a es verdadero y (B o C) es cierto.

1

Está cambiando la condición cuando agrega los paréntesis.

En el caso inicial el conjunto de resultados consiste en aquellos registros que cumplen las condiciones

`date_next_payment` <= '2011-02-02' AND `status` = 'active' 

o la condición

`status` = 'past due'. 

Después de agregar el paréntesis, el conjunto de resultados constará de aquellos registros que satisfacer la condición

`date_next_payment` <= '2011-02-02' 

y cualquiera de las condiciones iones

`status` = 'active' 

o

`status` = 'past due' 
Cuestiones relacionadas