2009-01-12 16 views
40

Wikipedia estados:¿Cuándo o por qué usaría una unión externa derecha en lugar de izquierda?

"En la práctica, explícita externa derecha combinaciones se usan muy poco, ya que siempre se pueden sustituir por externa izquierda se une y no proporcionan una funcionalidad adicional."

¿Alguien puede proporcionar una situación donde han preferido usar la notación RIGHT, y por qué? No puedo pensar en una razón para usarlo alguna vez. Para mí, nunca dejaría las cosas más claras.

Editar: Soy un veterano de Oracle haciendo la Resolución de Año Nuevo para destetarme de la sintaxis (+). Quiero hacerlo bien

+1

O, dicho de otra manera, que quiere hacer las cosas bien y se fue (y completa) :) –

Respuesta

27

La única razón por la que se me ocurre usar RIGHT OUTER JOIN es tratar de hacer que su SQL sea más autodocumentado.

Es posible que desee utilizar combinaciones a la izquierda para consultas que tienen filas nulas en el lado dependiente (muchos) de las relaciones uno a muchos y uniones a la derecha en aquellas consultas que generan filas nulas en el lado independiente.

Esto también puede ocurrir en el código generado o si los requisitos de codificación de una tienda especifican el orden de declaración de las tablas en la cláusula FROM.

+2

1, sería aceptar la respuesta si se resume el suyo, Michael, y Iván. – DCookie

+1

podemos obtener los mismos resultados usando la combinación externa izquierda (por cierto conseguimos usar la combinación externa derecha). ¿Por qué hay una opción para la unión correcta o viceversa ?. –

5

La única vez que pensaría en una combinación externa correcta es si estuviera arreglando una combinación completa, y simplemente sucedió que necesitaba el resultado para contener todos los registros de la tabla de la derecha. Sin embargo, aunque soy tan flojo como yo, probablemente me enojaría tanto que lo reorganizaría para usar una combinación izquierda.

Este ejemplo muestra Wikipedia de lo que quiero decir:

SELECT * 
FROM employee 
    FULL OUTER JOIN department 
     ON employee.DepartmentID = department.DepartmentID 

Si acaba de sustituir la palabra FULL con RIGHT que tienen una nueva consulta, sin tener que cambiar el orden de la cláusula ON.

+0

¿Cómo llegó la declaración FULL en primer lugar? ¿Una pregunta confusa mal escrita? – dkretz

+3

'FULL' tiene su propósito, y no siempre necesita" fijación ", y reemplazarlo con' RIGHT' no hace lo mismo. ¿Qué sucede si está elaborando un informe para ayudar a la empresa a validar las asignaciones del departamento de empleados y desea incluir departamentos que no tienen empleados y empleados que no han sido asignados a un departamento? – utexaspunk

1

Las sentencias SQL, además de ser correctas, deben ser lo más fáciles de leer y expresivamente concisas posible (porque representan acciones atómicas individuales, y su mente necesita asimilarlas por completo para evitar consecuencias involuntarias). A veces, una expresión es más claramente indicado con una combinación externa derecha.

Pero uno siempre se puede transformar en el otro, y el optimizador funcionará tan bien con uno como el otro.

Durante un tiempo, al menos uno de los principales productos rdbms solo es compatible con LEFT OUTER JOIN. (Creo que era de MySQL.)

+1

"A veces, una expresión se expresa más claramente con una combinación externa derecha". Estoy luchando con cuando ese podría ser el caso. ¿Por qué utilizar una sintaxis que es básicamente la inversa de otra, más utilizada? ¿Tienes un ejemplo? – DCookie

+1

No. Nunca he usado DERECHO EXTERIOR ÚNASE A MI: D. – dkretz

7

B RIGHT JOIN A es el mismo que A LEFT JOIN B

B RIGHT JOIN A lee: B a la derecha, encuentra entonces con A. significa que el A está en el lado izquierdo de conjunto de datos. de la misma manera que UNA UNIÓN IZQUIERDA B

No hay rendimiento que pueda obtenerse si va a reorganizar UNIONES IZQUIERDAS a la DERECHA.

Las únicas razones que puedo pensar por qué se usaría RIGHT JOIN es si usted es el tipo de persona que le gusta pensar desde adentro hacia afuera (seleccione * del detalle right join header). Es como otros como little-endian, otros como big-endian, otros como diseño de arriba hacia abajo, otros como diseño bottom up.

La otra es si ya tiene una consulta enorme en la que desea agregar otra tabla, cuando es un dolor en el cuello para reorganizar la consulta, así que simplemente conecte la tabla a la consulta existente utilizando DERECHO A UNIRSE.

+0

+1, aceptaría la respuesta si resumía la tuya, la de Jekke y la de Ivan. – DCookie

2
SELECT * FROM table1 [BLANK] OUTER JOIN table2 ON table1.col = table2.col 

sustituya [blanco] con:

IZQUIERDA - si desea que todos los registros de la tabla 1, incluso si no tienen un col que coincide con la Tabla2 (También se incluyen los registros Table2 con partidos)

DERECHO - Si desea que todos los registros de tabla2 incluso si no tienen un col que coincide con la tabla1 (también se incluyen los registros tabla1 con partidos)

FULL - si desea que todos los registros de tabla1 y tabla2 de

¿De qué están hablando todos? Son lo mismo? No lo creo.

+2

Siempre puede reemplazar una UNIÓN EXTERIOR DERECHA con una UNIÓN EXTERIOR IZQUIERDA que produce la misma respuesta, y viceversa. – DCookie

+0

¿Quiere decir que acaba de intercambiar las palabras "IZQUIERDA" y "DERECHA" o quiere decir que no entiende la sintaxis de la consulta? –

+3

tiene que cambiar el orden de las tablas en la unión también. – HLGEM

2

Las únicas veces que he usado una unión correcta han sido cuando quiero ver dos conjuntos de datos y ya tengo las uniones en un orden específico para la combinación izquierda o interna de una consulta previamente escrita. En este caso, supongamos que quiere ver como un conjunto de datos los registros no incluidos en la tabla a pero en la tabla b y en otra los registros no en la tabla b sino en la tabla a. Incluso entonces, solo tiendo a hacer esto para ahorrar tiempo investigando, pero lo cambiaría si fuera un código que se ejecutaría más de una vez.

2
SELECT * FROM table_a 
INNER JOIN table_b ON .... 
RIGHT JOIN table_c ON .... 

¿Cómo podría rápidamente/fácilmente combinación interna las 2 primeras mesas y unirse a table_c garantizando al mismo tiempo todas las filas de table_c siempre se seleccionan?

+5

Puedes enumerar table_c primero y unirlo a los demás. – DCookie

+0

Escribiendo a cabo, @ sintaxis de Matt parece más fácil de leer que el equivalente: 'SELECT * FROM table_c LEFT JOIN ( SELECT * FROM TABLE_A INNER JOIN table_b EN .... ) EN .... ' Usted – 8forty

14

Nunca antes había usado right join y nunca pensé que realmente podría necesitarlo, y parece un poco antinatural. Pero después pensé en ello, que podría ser muy útil en la situación, cuando es necesario combinación externa una tabla con intersección de muchas mesas, por lo que tiene tablas como esta:

enter image description here

y desea obtener como resultado de esta manera:

enter image description here

O, en SQL (MS SQL Server):

declare @temp_a table (id int) 
declare @temp_b table (id int) 
declare @temp_c table (id int) 
declare @temp_d table (id int) 

insert into @temp_a 
select 1 union all 
select 2 union all 
select 3 union all 
select 4 

insert into @temp_b 
select 2 union all 
select 3 union all 
select 5 

insert into @temp_c 
select 1 union all 
select 2 union all 
select 4 

insert into @temp_d 
select id from @temp_a 
union 
select id from @temp_b 
union 
select id from @temp_c 

select * 
from @temp_a as a 
    inner join @temp_b as b on b.id = a.id 
    inner join @temp_c as c on c.id = a.id 
    right outer join @temp_d as d on d.id = a.id 

id   id   id   id 
----------- ----------- ----------- ----------- 
NULL  NULL  NULL  1 
2   2   2   2 
NULL  NULL  NULL  3 
NULL  NULL  NULL  4 
NULL  NULL  NULL  5 

Entonces, si cambia al left join, los resultados no serán los mismos.

select * 
from @temp_d as d 
    left outer join @temp_a as a on a.id = d.id 
    left outer join @temp_b as b on b.id = d.id 
    left outer join @temp_c as c on c.id = d.id 

id   id   id   id 
----------- ----------- ----------- ----------- 
1   1   NULL  1 
2   2   2   2 
3   3   3   NULL 
4   4   NULL  4 
5   NULL  5   NULL 

La única manera de hacer esto sin derecho JOIN es utilizar una expresión de tabla común o subconsulta

select * 
from @temp_d as d 
    left outer join (
     select * 
     from @temp_a as a 
      inner join @temp_b as b on b.id = a.id 
      inner join @temp_c as c on c.id = a.id 
    ) as q on ... 
+4

no es necesario anidar un SELECT, puede anidar una unión en su lugar: 'FROM @temp_d AS d IZQUIERDA OUTER JOIN (temp_a COMO UNIÓN INTERNA @temp_b AS b ON b.id = a.id UNIÓN INTERNA @temp_c AS c ON c.id = a.id) ON a.id = d.id'. (Los corchetes son innecesarios, se agregan solo para facilitar la lectura.) Sin embargo, es cierto que hay personas que no están decididas sobre qué sintaxis aborrecen más, uniones anidadas o uniones externas a la derecha, por lo que es posible que las combinaciones correctas funcionen * menos mal * para ellos. :) –

+0

Bueno, nunca utilicé la sintaxis de uniones anidadas :) –

2

Realmente no he tenido que pensar mucho a la derecha entrar, pero supongo que yo En 20 años, desde que escribí las consultas SQL, no encontré una justificación sólida para usar una. Ciertamente, he visto muchos de ellos, supongo, que surgen de los desarrolladores que han utilizado constructores de consultas integrados.

Siempre que he encontrado uno, he reescrito la consulta para eliminarlo - He encontrado que solo requieren demasiada energía mental adicional para aprender o volver a aprender si no has visitado la consulta durante un tiempo y no ha sido raro que la intención de la consulta se pierda o devuelva resultados incorrectos, y generalmente es esta incorrección la que me ha llevado a solicitar que revise por qué las consultas no funcionaban.

Al pensar en ello, una vez que introduces una combinación de la derecha, ahora tienes lo que consideraría ramas de la lógica competitiva que deben encontrarse en el medio. Si se introducen requisitos/condiciones adicionales, ambas ramas se pueden extender aún más y ahora tiene más complejidad que tiene que hacer malabares para asegurarse de que una rama no da lugar a resultados incorrectos.

Además, una vez que introduce una combinación correcta, otros desarrolladores menos experimentados que trabajan en la consulta más tarde simplemente pueden atornillar en tablas adicionales a la parte de la derecha de la consulta y, al hacerlo, expandir los flujos lógicos que compiten aún necesidad de reunirse en el medio; o en algunos casos que he visto, comienzan a anidar vistas porque no quieren tocar la lógica original, tal vez en parte, esto se debe a que es posible que no comprendan la consulta o las reglas comerciales vigentes que impulsaron la lógica.

0

En algunas bases de datos SQL, hay sugerencias del optimizador que le dicen al optimizador que una las tablas en el orden en que aparecen en la cláusula FROM, p. /*+ORDERED */ en Oracle. En algunas implementaciones simples, este podría ser el único plan de ejecución disponible.

En tales casos, el orden de las tablas en la cláusula FROM es importante para que RIGHT JOIN pueda ser útil.

0

Creo que es difícil si no tiene derecho de unirse en este caso. ex con oráculo

with a as(
    select 1 id, 'a' name from dual union all 
    select 2 id, 'b' name from dual union all 
    select 3 id, 'c' name from dual union all 
    select 4 id, 'd' name from dual union all 
    select 5 id, 'e' name from dual union all 
    select 6 id, 'f' name from dual 
), bx as(
    select 1 id, 'fa' f from dual union all 
    select 3 id, 'fb' f from dual union all 
    select 6 id, 'f' f from dual union all 
    select 6 id, 'fc' f from dual 
) 
select a.*, b.f, x.f 
from a left join bx b on a.id = b.id 
right join bx x on a.id = x.id 
order by a.id 
+0

'seleccionar a. *, Bf, xf de bx x left outer join a en aid = x.id left join bx b en b.id = a .id pedido por a.id' – JohnLBevan

Cuestiones relacionadas