2011-01-24 8 views
13

Tengo curiosidad de por qué tenemos que usar LEFT JOIN ya que podemos usar comas para seleccionar varias tablas.Unir a la izquierda o seleccionar de varias tablas usando coma (,)

¿Cuáles son las diferencias entre LEFT JOIN y el uso de comas para seleccionar varias tablas.

¿Cuál es más rápido?

Aquí está mi código:

SELECT mw.*, 
      nvs.* 
    FROM mst_words mw 
LEFT JOIN (SELECT no as nonvs, 
        owner, 
        owner_no, 
        vocab_no, 
        correct 
      FROM vocab_stats 
      WHERE owner = 1111) AS nvs ON mw.no = nvs.vocab_no 
    WHERE (nvs.correct > 0) 
     AND mw.level = 1 

... y:

SELECT * 
    FROM vocab_stats vs, 
     mst_words mw 
WHERE mw.no = vs.vocab_no 
    AND vs.correct > 0 
    AND mw.level = 1 
    AND vs.owner = 1111 
+1

El primero es un ejemplo de UNIÓN EXTERIOR (en este caso, IZQUIERDA) (ANSI-92), este último es UNIÓN ÚNICA (ANSI-89, que no admite uniones EXTERNAS). A menos que siempre haya un registro para vincular las dos tablas, es poco probable que devuelvan los mismos resultados. –

+0

@OMG El último es 'no 'INNER JOIN. Está más cerca de una UNIÓN CRUZADA por definición ya que es un producto cartesiano. – RichardTheKiwi

+1

Sintaxis ANSI-89 ... el plan de explicación es idéntico al uso de '... DE VOCAB_STATS s UNIR MSTWORDS w ON w.no = v.vocab_no ...'. Nuevamente, ** no, la segunda consulta no devuelve un producto cartesiano **. –

Respuesta

3

En primer lugar, para ser completamente equivalentes, la primera consulta debería haber sido escrito

SELECT mw.*, 
      nvs.* 
    FROM mst_words mw 
LEFT JOIN (SELECT * 
      FROM vocab_stats 
      WHERE owner = 1111) AS nvs ON mw.no = nvs.vocab_no 
    WHERE (nvs.correct > 0) 
     AND mw.level = 1 

Para que mw * y nvs * en conjunto producen el mismo conjunto como la segunda consulta es singular *. La consulta, tal como la ha escrito, puede usar INNER JOIN, ya que incluye un filtro en nvs.correct.

La forma general

TABLEA LEFT JOIN TABLEB ON <CONDITION> 

attempts para encontrar registros TableB basado en la condición. Si falla, se conservan los resultados de TABLEA, con todas las columnas de TableB establecidas en NULL. En contraste

TABLEA INNER JOIN TABLEB ON <CONDITION> 

también attempts para encontrar registros TableB basado en la condición. Sin embargo,, cuando falla, el registro particular de TableA se elimina del conjunto de resultados de salida.

El estándar ANSI para CROSS JOIN produce un Cartesian product entre las dos tablas.

TABLEA CROSS JOIN TABLEB 
    -- # or in older syntax, simply using commas 
TABLEA, TABLEB 

La intención de la sintaxis es que cada fila de la TablaA se une a cada fila de TABLEB. Entonces 4 filas en A y 3 filas en B producen 12 filas de salida. Cuando se combina con las condiciones en la cláusula WHERE, a veces produce el mismo comportamiento de INNER JOIN, ya que expresan lo mismo (condición entre A y B => mantener o no). Sin embargo, es mucho más claro cuando se lee en cuanto a la intención cuando se usa INNER JOIN en lugar de comas.

En cuanto a rendimiento, la mayoría de los DBMS procesarán una combinación IZQUIERDA más rápido que una UNIÓN INTERNA. La notación de coma puede hacer que los sistemas de bases de datos malinterpreten la intención y produzcan un plan de consulta incorrecto, por lo que es una ventaja adicional para la notación SQL92.

¿Por qué necesitamos LEFT JOIN? Si la explicación de LEFT JOIN anterior aún no es suficiente (mantenga registros en A sin coincidencias en B), entonces considere que para lograr lo mismo, necesitaría una UNIÓN compleja entre dos conjuntos usando la notación de coma antigua para lograr el mismo efecto. Pero como se indicó anteriormente, esto no se aplica a su ejemplo, que en realidad es una UNIÓN INTERNA que se esconde detrás de una UNIÓN IZQUIERDA.

Notas:

  • La RIGHT JOIN es el mismo que el IZQUIERDA, excepto que se inicia con TABLEB (lado derecho) en lugar de A.
  • derecha e izquierda Las combinaciones se une tanto EXTERIOR. La palabra OUTER es opcional, es decir, se puede escribir como LEFT OUTER JOIN.
  • El tercer tipo de unión EXTERIOR es la unión FULL OUTER, pero eso no se trata aquí.
0

La separación de la unión de la DONDE hace que sea fácil de leer, ya que la lógica de unirse no puede confundirse con las condiciones DONDE. En general, también será más rápido, ya que el servidor no necesitará realizar dos consultas separadas y combinar los resultados.

Los dos ejemplos que ha dado no son realmente equivalentes, ya que ha incluido una sub consulta en el primer ejemplo. Este es un ejemplo mejor:..

SELECT vs.*, mw.* 
FROM vocab_stats vs, mst_words mw 
LEFT JOIN vocab_stats vs ON mw.no = vs.vocab_no 
WHERE vs.correct > 0 
AND mw.level = 1 
AND vs.owner = 1111 
+0

El SQL no es válido – RichardTheKiwi

+0

Gracias, acabo de eliminar el error tipográfico. – Bazmatiq

Cuestiones relacionadas