2012-04-23 29 views
5

que tiene esta línea en mi consulta SQL:consulta SQL en la cláusula

WHERE client = $id 
    AND (isinvoiced = 0) OR (isinvoiced = 1 and isrecurring = 1) 

que obtiene más resultados que estoy esperando. Sin embargo, si escribo de esta manera:

WHERE client = $id 
    AND (isinvoiced = 0) OR (isinvoiced = 1 and isrecurring = 1 and client = $id) 

entonces me consigue los resultados que quería, pero esta es la mejor manera de escribir esto? Simplemente no quiero encontrar más problemas con este código.

+1

Google para [Reglas de reescritura de la distribución] (http://en.wikipedia.org/wiki/Distributivity). – onedaywhen

+2

¿Estás seguro de que entiendes la diferencia entre 'a AND b OR c' y 'a AND (b OR c)'? Su ejemplo está escrito más claramente como '(a AND b) OR c', no lo que realmente quiere. – MatBailie

Respuesta

8

Necesita un conjunto más de () en toda la cláusula AND. Esto indica que client = $id DEBE ser verdadero, y cualquiera de las otras condiciones también debe ser verdadero = isinvoiced = 0 O la combinación de isinvoiced = 1 and isrecurring = 1.

WHERE client = $id 
    AND ((isinvoiced = 0) OR (isinvoiced = 1 and isrecurring = 1)) 
+0

Perfecto Michael, eso es exactamente lo que estoy buscando, gracias de nuevo ... Votaré por tu respuesta cuando me lo permita. – user979331

+1

Si 'isinvoiced = 1' es exactamente el caso opuesto de' isinvoiced = 0' (es decir, 'isinvoiced' no puede contener ningún otro valor, ni' NULL'), puede simplificarlo aún más: 'WHERE client = $ id AND (isinvoiced = 0 OR isrecurring = 1) '. –

1
where client = $id 
    and (
     isinvoiced = 0 
     or (
      isinvoiced = 1 
      and isrecurring = 1 
      ) 
     ) 
-1

Si se quita la cláusula inicial en la que

remove -> WHERE client = $id 

y acaban de

WHERE (isinvoiced = 0) OR (isinvoiced = 1 and isrecurring = 1 and client = $id) 

¿Eso se obtiene los resultados que desea?

+0

El OP quiere coincidir con 'client' todo el tiempo. Ver la respuesta aceptada. – Ben

2

Añadir un paréntesis alrededor de su cláusula de AND:

WHERE client = $id 
    AND ((isinvoiced = 0) OR (isinvoiced = 1 and isrecurring = 1)) 
1

Lo que quiere decir esto:

WHERE client = $id AND ((isinvoiced = 0) OR (isinvoiced = 1 and isrecurring = 1)) 

Si usted no pone los Blaquets adicionales se hará una OR con el cliente restiction y da más resultados.

0

En lo que respecta a SQL, debe intentar escribir las condiciones de búsqueda en conjunctive normal form ("a seires of AND clauses"). Hay varios rewrite rules para ayudar en esto.

El distributive rewrite law es útil en este caso es decir

(P AND Q) OR R <=> (P OR R) AND (Q OR R)  

En su caso:

(isinvoiced = 0) OR (isinvoiced = 1 AND isrecurring = 1) 

puede reescribirse como:

(isinvoiced = 0 OR isinvoiced = 1) AND (isinvoiced = 0 OR isrecurring = 1) 

Por lo tanto, el conjunto condición de búsqueda sin difícil de manejar parens:

.... 
WHERE client = $id 
     AND (isinvoiced = 0 OR isinvoiced = 1) 
     AND (isinvoiced = 0 OR isrecurring = 1); 
Cuestiones relacionadas