2010-07-07 19 views
6

Tengo tres tablas, 'A', 'B' y 'C'. Tengo una consulta sobre 'A' y 'B', pero quiero agregar un campo que me diga si hay una o más (no me importa cuántas) 'C' que tienen una clave externa para 'A'.¿Una mejor manera de devolver '1' si una combinación a la izquierda devuelve cualquier fila?

Esto es lo que tengo:

SELECT A.A_id, A.col_2, col_3, B.col_2, A.col_4 
      count(C.id) as C_count 
FROM  A 
JOIN  B ON (A.B_id = B.B_id) 
LEFT JOIN C ON (A.A_id = C.A_id) 
WHERE  A.A_id = ? 
GROUP BY A.A_id, A.col_2, col_3, B.col_2, A.col_4 
ORDER BY CASE WHEN A.col_2 = ? 
       THEN 0 
       ELSE 1 
      END, col_3; 

parece un poco ineficiente, tanto porque tengo que enumerar todos los campos de la GROUP BY y también porque estoy contando, donde todo lo que realmente quiero es si existe al menos un partido o no. ¿Se puede mejorar esto?

+1

El hecho de que había que escribir una gran cantidad de nombres de columna no hace una consulta ineficaz;) En este caso, sin embargo, estás en lo correcto. Ordenando y tabulando el recuento es costoso, pero tal vez incluso más costoso es que el DB tiene que pasar por TODAS las filas en la Tabla C para obtener ese conteo. Con la solución EXISTS, tan pronto como encuentre la primera fila coincidente, puede dejar de buscar. –

+0

Buena explicación, @Tom. –

Respuesta

13

uso existe con una subconsulta en lugar ...

Select A.A_id, A.col_2, col_3, 
    B.col_2, A.col_4, 
    Case When Exists (Select * From C 
         Where A_id = A.A_id) 
     Then 1 Else 0 End As C_Exists 
From A Join B 
    On (A.B_id = B.B_id) 
Where A.A_id = ?  
Order By Case When A.col_2 = ? 
      Then 0 Else 1 End, col_3; 
+0

+1 para existe :-) – corsiKa

+0

Excelente. El PLAN EXPLICADO dice que es mejor también. 3 minutos hasta que pueda aceptarlo. –

+1

@Paul Tomblin: Esto se debe a que EXISTS volverá a ser cierto tan pronto como se encuentre la primera coincidencia exitosa con los criterios: no es necesario que EXISTS verifique todos los criterios coincidentes. –

Cuestiones relacionadas