2009-01-23 14 views
13

tengo 3 mesas y tengo que combinación interna Tabla A con la Tabla B, pero una combinación externa izquierda entre la tabla A y en la Tabla C.SQL Server - Combinando exterior e interior se une

¿Puedo combinar exterior e interior se unen en el misma consulta? Puedo anidar consultas y lograr el resultado deseado, pero no puedo hacer ambas uniones en la misma consulta. Parece que en otros lenguajes SQL, el orden de unión es importante. ¿Es este el caso en SQL Server también?


Bien, aquí está el escenario.

Considere 3 tablas. Tabla A, Tabla F, Tabla D.

Necesitaré que el conjunto de registros contenga todas las filas en D, independientemente de si existe en F (después de que se haya unido internamente con A). Entonces, una combinación externa viene a la mente. Lo que se necesita es:

  1. En primer lugar hacer unirse a una interna entre A y F para obtener un conjunto (esto puede ser un conjunto nulo)
  2. luego hacer una combinación externa con el conjunto de registros en (1) con D

Respuesta

4

asegúrese de poder hacer la unión en la misma consulta: -

FROM TableA a 
INNER JOIN Table b ON a.TableA_ID = b.TableA_ID 
LEFT OUTER JOIN Table c ON a.TableA_ID = c.TableA_ID 
+0

Eso no da todas las filas en la Tabla D (que llama c) – Paparazzi

0

Sí se puede hacer ambas cosas es la misma consulta, y sí el orden es importante.

13

si he entendido bien quieres algo como esto:

select 
    * 
from 
    a 
    left outer join c 
     inner join b on c.bID = b.ID 
    on a.cID = c.ID 
+3

¡Tricky! Si mueve "on a.cID = c.ID" a justo debajo de "left outer join c", esto no da los mismos resultados, ¿o simplemente me falta algo? ¿Este comportamiento está documentado en alguna parte? No me di cuenta de que el encendido no tenía que seguir directamente la unión. – Brandon

+0

Creo que tiene a yc al revés – Paparazzi

1

Desde su seguimiento, parece que usted quiere unirse a un 'condicional' interior.

Esencialmente, un "Si A y B tienen un registro, INNER JOIN to C".

Sin embargo, es probable que se encuentre con el problema donde INNER JOIN en su consulta no muestra registros donde A no tiene registros asociados a B o C. Si están en el mismo 'alcance', INNERS siempre se ejecutará , no puede hacer que se ejecuten de manera condicional en función de su orden.

O bien tiene que utilizar dos uniones IZQUIERDA y filtrar los registros que no desea, o bien utilizar una Vista para determinar el alcance de la UNIÓN INTERNA.

Ej. A LEFT JOIN vw_MyView ON A.ID = vw_MyView.A_ID

Donde MyView tiene tablas B y C con INNER JOIN. Esto permitirá que INNER JOIN se ejecute dentro de la vista, y luego puede LEFT JOIN a los resultados.

2

La orden no debe importarse.

Venn Diagram

Aquí hay un diagrama de Venn de Wikimedia Commons.Independientemente del orden de consulta, obtendrá la superposición entre los círculos A y B, con nulos para las columnas de C donde C no solapa la combinación de A y B.

0

El problema puede no ser específicamente la unión (Anthony te mostró cómo hacer lo que nos describiste). Recuerda que las personas a menudo tienen problemas para usar las uniones izquierdas porque intentan poner algo en la cláusula where que hace referencia a la tabla del lado derecho de la unión, convirtiéndola de una combinación externa a una combinación interna (a menos que esté buscando aquellos registros donde el segundo campo de tabla es nulo, lo que le da los registros en la primera tabla y no en la segunda).

Podríamos ayudarlo mejor si decimos que el código real que estaba utilizando no estaba produciendo los resultados deseados, así como algunos datos de muestra y resultados de muestras.

7

Para mi caso, tenía que poner los alias de tabla para mi consulta para que funcione correctamente:

SELECT * FROM ("purchased_items" p1 
    INNER JOIN "purchase_orders" po1 ON (po1."id" = p1."purchase_order_id")) AS p4 
LEFT OUTER JOIN (purchased_items p2 
     INNER JOIN "purchase_orders" po2 ON (po2."id" = p2."purchase_order_id")) AS p5 
ON (p4.item_variant_id = p5.item_variant_id AND p4.delivery_date < p5.delivery_date) 
WHERE p5.delivery_date IS NULL AND p4.delivered <> 0 
+1

Solo necesito decir que este comentario me ayudó muchísimo. Era dónde poner el paréntesis y cómo unir las tablas correctamente que estaba atascado cuando intento varias combinaciones de unión interna y combinación externa izquierda. ¡Gracias! – nzifnab

+0

Tuve que agregar una cláusula 'select blah from' para p5. [Esto ayudó] (http://weblogs.sqlteam.com/jeffs/archive/2007/10/11/mixing-inner-outer-joins-sql.aspx) – Jess

0

Esto viene a colación de 1 a cero o muchos, donde los muchos tiene una FK.

dos enfoques
orden del on
puso el outer unen última

Desafortunada ha cambiado los nombres de tabla. Usaré los nombres posteriores.

declare @TableD TABLE (PeopleID int primary key, Name varchar(10)); 
INSERT INTO @TableD VALUES 
     (1, 'Chris') 
    , (2, 'Cliff') 
    , (3, 'Heather'); 

declare @TableA TABLE (ThingID int primary key, ThingName varchar(10)) 
INSERT INTO @TableA VALUES 
     (14, 'Bike') 
    , (17, 'Trailer') 
    , (18, 'Boat'); 

declare @TableF TABLE (PeopleID int, ThingID int, primary key (PeopleID, ThingID)); 
INSERT INTO @TableF VALUES 
     (1, 18) 
    , (1, 17) 
    , (2, 14); 

SELECT D.Name, A.ThingName 
FROM @TableD D 
LEFT JOIN @TableF F 
    JOIN @TableA A 
     ON A.ThingID = F.ThingID 
    ON F.PeopleID = D.PeopleID 
order by D.Name, A.ThingName; 

SELECT D.Name, A.ThingName 
FROM @TableF F 
JOIN @TableA A 
    ON A.ThingID = F.ThingID 
right join @TableD D 
    ON D.PeopleID = F.PeopleID 
order by D.Name, A.ThingName; 

Name  ThingName 
---------- ---------- 
Chris  Boat 
Chris  Trailer 
Cliff  Bike 
Heather NULL 
Cuestiones relacionadas