¿Cómo puede un LEFT OUTER JOIN devolver más registros de los que existen en la tabla de la izquierda?

165

Tengo una BÚSQUEDA EXTERIOR IZQUIERDA muy básica para devolver todos los resultados de la tabla de la izquierda y alguna información adicional de una tabla mucho más grande. La tabla de la izquierda contiene 4935 registros, pero cuando dejé que me uniera a una tabla adicional, el recuento de registros es significativamente mayor.

Hasta donde sé, es un evangelio absoluto que una IZQUIERDA EXTERIOR IZQUIERDA devolverá todos los registros de la tabla izquierda con registros coincidentes de la tabla derecha y valores nulos para cualquier fila que no pueda coincidir, como tal, entiendo que debería será imposible devolver más filas de las que existen en la tabla de la izquierda, ¡pero está sucediendo de todos modos!

La consulta SQL sigue:

SELECT     SUSP.Susp_Visits.SuspReason, SUSP.Susp_Visits.SiteID
FROM         SUSP.Susp_Visits LEFT OUTER JOIN
                      DATA.Dim_Member ON SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum

Tal vez he cometido un error en la sintaxis o mi comprensión de LEFT OUTER JOIN es incompleta, ¿espero que alguien pueda explicar cómo podría estar ocurriendo esto?

Posdata

Gracias por las excelentes respuestas, mi comprensión de LEFT OUTER JOINS ahora es mucho mejor, ¿podría alguien sugerir una forma de modificar esta consulta para que solo se devuelvan tantos registros como existen en la tabla de la izquierda?

Esta consulta es puramente para generar un informe y las coincidencias duplicadas simplemente confunden las cosas.

/Posdata

Jay Wilde
fuente
55
Para "obtener tantos registros devueltos como existan en la tabla izquierda", debe especificar qué fila del lado derecho elegir si hay varias coincidencias.
AK
1
¿Cómo se especifica esto? Me gustaría que me devolvieran el primer partido.
Simon Cross
1
tienes que definir qué se entiende por el primer partido. ¿Quieres el primer registro, el que tiene la identificación más alta o qué?
HLGEM
1
Si coincide con la clave principal en una tabla adicional, su declaración es correcta.
Prageeth godage
A menudo uso un recurso como este como una hoja de trucos cuando construyo consultas. Si el enlace alguna vez muere, solo únete a google sql ; son diagramas de Venn de los diferentes tipos de unión.
Zimano

Respuestas:

190

La IZQUIERDA EXTERIOR IZQUIERDA devolverá todos los registros de la tabla IZQUIERDA unida con la tabla DERECHA siempre que sea posible.

Sin embargo, si hay coincidencias, aún devolverá todas las filas que coinciden, por lo tanto, una fila a la IZQUIERDA que coincida con dos filas en la DERECHA volverá como dos FILAS, al igual que una UNIÓN INTERNA.

EDITAR: en respuesta a su edición, acabo de revisar su consulta y parece que solo está devolviendo datos de la tabla IZQUIERDA. Por lo tanto, si solo desea datos de la tabla IZQUIERDA, y solo desea que se devuelva una fila por cada fila en la tabla IZQUIERDA, entonces no tiene necesidad de realizar una UNIÓN y simplemente puede hacer un SELECCIONAR directamente desde la tabla IZQUIERDA.

Día de robin
fuente
1
La razón para unirme a la tabla de la derecha fue que solo obtuve registros de la izquierda donde había al menos un registro en la tabla de la derecha, pero muchas gracias por la explicación.
Jay Wilde
125
Table1                Table2
_______               _________
1                      2
2                      2
3                      5
4                      6

SELECT Table1.Id, Table2.Id FROM Table1 LEFT OUTER JOIN Table2 ON Table1.Id=Table2.Id

Resultados:

1,null
2,2
2,2
3,null
4,null
Andrew Lewis
fuente
1
Tan simple y tan poderoso.
kiradotee
39

No es imposible El número de registros en la tabla de la izquierda es el número mínimo de registros que devolverá. Si la tabla derecha tiene dos registros que coinciden con un registro en la tabla izquierda, devolverá dos registros.

HLGEM
fuente
12

En respuesta a tu postdata, eso depende de lo que quieras.

Está obteniendo (posible) varias filas para cada fila en su tabla izquierda porque hay múltiples coincidencias para la condición de unión. Si desea que sus resultados totales tengan el mismo número de filas que hay en la parte izquierda de la consulta, debe asegurarse de que sus condiciones de unión causen una coincidencia de 1 a 1.

Alternativamente, dependiendo de lo que realmente quiera, puede usar funciones agregadas (si, por ejemplo, solo desea una cadena de la parte derecha, podría generar una columna que sea una cadena delimitada por comas de los resultados del lado derecho para esa fila izquierda.

Si solo está mirando 1 o 2 columnas de la unión externa, puede considerar usar una subconsulta escalar ya que se le garantizará 1 resultado.

Chris Cameron-Mills
fuente
44
Esta es una buena respuesta, ya que ofreció sugerencias sobre cómo devolver solo filas de la tabla izquierda.
karns
9

Cada registro de la tabla izquierda se devolverá tantas veces como haya registros coincidentes en la tabla derecha, al menos 1, pero fácilmente podría ser más de 1.

Alex Martelli
fuente
8

IZQUIERDA EXTERIOR UNIR al igual que INNER JOIN (unión normal) devolverá tantos resultados para cada fila en la tabla izquierda como tantas coincidencias que encuentre en la tabla derecha. Por lo tanto, puede obtener muchos resultados, hasta N x M, donde N es el número de filas en la tabla izquierda y M es el número de filas en la tabla derecha.

Es el número mínimo de resultados que siempre se garantiza en IZQUIERDA EXTERIOR UNIR para ser al menos N.

el mejor chef
fuente
1
Empecé a pensar cuando el número de filas es igual a N x M y la única situación real que se me ocurre es cuando N o M es igual a 1. ¿Estás de acuerdo?
BartoszMiller
2
No lo hago No debe pensar en la condición de unión como la igualdad de clave solo. Puede ser una condición arbitraria, por ejemplo, rangos de fechas, desigualdades, etc. Dos casos extremos: (a) N filas no tienen una sola coincidencia entre M filas, luego la combinación externa izquierda da como resultado N filas coincidentes con NULL. (b) cada una de las N filas coincide con todas las M filas, luego el resultado es N x M filas establecidas.
topchef
1
Tienes razón, estaba pensando en las uniones solo en términos de igualdad clave. Me gusta su ejemplo del "caso b". Creo que "cada una de las N filas coincide con todas las M filas" es una receta general para cuando se devuelven N x M filas, lo cual es bastante imposible de visualizar cuando se piensa solo en la igualdad de claves.
BartoszMiller
7

¿Podría ser una relación de uno a muchos entre las tablas izquierda y derecha?

Ken Burkhardt
fuente
6

Preste atención si tiene una cláusula where en la tabla "lado derecho" de una consulta que contiene una unión externa izquierda ... En caso de que no tenga ningún registro en el lado derecho que satisfaga la cláusula where, entonces el registro correspondiente del lado "izquierdo" 'la tabla no aparecerá en el resultado de su consulta ...

Sarga
fuente
1
A continuación, debe agregar la condición a la cláusula ON de la UNIDAD EXTERIOR IZQUIERDA correspondiente.
Mik
6

Si necesita una sola fila desde el lado derecho

SELECT SuspReason, SiteID FROM(
    SELECT SUSP.Susp_Visits.SuspReason, SUSP.Susp_Visits.SiteID, ROW_NUMBER()
    OVER(PARTITION BY SUSP.Susp_Visits.SiteID) AS rn
    FROM SUSP.Susp_Visits
    LEFT OUTER JOIN DATA.Dim_Member ON SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum
) AS t
WHERE rn=1

o solo

SELECT SUSP.Susp_Visits.SuspReason, SUSP.Susp_Visits.SiteID
FROM SUSP.Susp_Visits WHERE EXISTS(
    SELECT DATA.Dim_Member WHERE SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum
)
Alaska
fuente
1
Debido a que no proporcionó DDL y DML, no lo probé. De todos modos, creo que EXISTE es lo que quieres. Intente esto: SELECCIONE SuspReason, SiteID FROM (SELECT SUSP.Susp_Visits.SuspReason, SUSP.Susp_Visits.SiteID, ROW_NUMBER () OVER (PARTICIÓN POR SUSP.Susp_Visits.SiteID ORDER BY SUSP.Susp_Visits.SiteID) AS rn FROM SUSP.SUSP_USTT LEFTU LUSTER_SUST_SU_SUP_LUST_SU ÚNETE A DATA.Dim_Member EN SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum) COMO t DONDE rn = 1
AK
2

Parece que hay varias filas en la tabla DATA.Dim_Member por fila SUSP.Susp_Visits.

bdukes
fuente
2

Si varias (x) filas en Dim_Member están asociadas con una sola fila en Susp_Visits, habrá x filas en el conjunto resultante.

Manu
fuente