2011-08-24 22 views
6

Tengo un problema con una vista que quiero crear. Tengo dos tablas unidas en una combinación externa izquierda, digamos tableA y tableB, donde tableB se deja unir al exterior.SQL where cláusula para la combinación externa izquierda

Quiero seleccionar solo aquellas filas de la tabla B donde el estado es igual a 4, entonces agrego WHERE state = 4 a mi consulta. Ahora el conjunto de resultados se recorta un poco porque todas las filas sin una fila coincidente en tableB se eliminan del resultado (ya que el estado no es 4 para esas filas). También intenté WHERE state = 4 OR state IS NULL, tampoco funciona (ya que state técnicamente no es NULL cuando no hay estado).

Entonces, ¿qué necesito es una declaración WHERE que solo se evalúa cuando realmente hay una fila, existe tal cosa?

Si no, veo dos opciones: join (SELECT * FROM tableB WHERE state = 4) en lugar de la tabla B, o crear una vista con la misma instrucción WHERE y unir eso en su lugar. ¿Cuál es la mejor opción en cuanto a rendimiento?

Esto es SQL Server 2008 R2 por cierto.

+1

sería interesante tratar de averiguar por qué 'DONDE estado = 4 o un estado null' no funciona, ya que debe evitar que la combinación izquierda de convertirse en un interior unirse. –

+0

@Damien_The_Unbeliever - Le daría todas las filas de TableA no en TableB pero no en las filas donde TableA tiene una coincidencia en TableB donde state <> 4. http://data.stackexchange.com/stackoverflow/qt/110316/ –

+0

@ Damien_The_Unbeliever: hay 3 estados: haciendo coincidir con estado = 4, haciendo coincidir con estado <> 4, no coincide – gbn

Respuesta

6

Pones las condiciones en la cláusula on. Ejemplo:

select a.this, b.that 
from TableA a 
left join TableB b on b.id = a.id and b.State = 4 
+0

¡Ah, no lo sabía! ¡Gracias! – Jasper

4

Puede agregar state = 4 a la condición de unión.

select * 
from T1 
    left outer join T2 
    on T1.T1ID = T2.T1ID and 
     T2.state = 4 
1

Incluso más fácil que una sub consulta se está expandiendo la on cláusula, similares;

select * 
from TableA a 
left join 
     TableB b 
on  a.b_id = b.id 
     and b.state = 4 

Todas las filas de la Tabla A aparecerán, y sólo los de la Tabla B con el estado 4.

SQL Server probablemente ejecutar la vista, ampliada on y subconsulta exactamente de la misma manera. Por lo que respecta al rendimiento, debería haber poca diferencia.

0

enfoque alternativo: (1) combinación interna a la Tabla B, donde el estado es igual a 4, (2) antijoin a la mesa B para encontrar filas que no existen, (3) la unión de los resultados:

SELECT A1.ID, A1.colA, B1.ColB 
    FROM tableA AS A1 
     INNER JOIN tableB AS B1 
      ON A1.ID = B1.ID 
      AND B1.state = 4 
UNION 
SELECT A1.ID, A1.colA, '{{MISSING}}' AS ColB 
    FROM tableA AS A1 
WHERE NOT EXISTS (
        SELECT * 
        FROM tableB AS B1 
        WHERE A1.ID = B1.ID 
       ); 

alternativa:

SELECT A1.ID, A1.colA, B1.ColB 
    FROM tableA AS A1 
     JOIN tableB AS B1 
      ON A1.ID = B1.ID 
      AND B1.state = 4 
UNION 
SELECT ID, colA, '{{NA}}' AS ColB 
    FROM tableA 
WHERE ID IN (
       SELECT ID 
       FROM tableA 
       EXCEPT 
       SELECT ID 
       FROM tableB 
      ); 
Cuestiones relacionadas