2012-02-24 16 views
17

Tengo una pregunta, pero realmente no sé cómo preguntarla! Por favor tengan paciencia conmigo:Postgresql - cómo obtener entradas en una tabla que no tienen una coincidencia en otra tabla

SELECT  sc.*, 
     scd.siteid, scd.desc_frontend 
FROM  shipping_code sc 
LEFT OUTER JOIN shipping_code_description scd 
    ON   scd.shippingid=sc.shippingid 
    AND   scd.siteid IN (SELECT siteid FROM site_international WHERE published='t') 

Para explicar lo anterior, tenemos códigos en una tabla llamada "shipping_code" envío (entrega), y, porque tenemos un sitio en varios idiomas, tenemos otra tabla de descripciones en lenguaje de esos códigos, en 'shipping_code_description'. También tenemos una tabla llamada "site_international" que tiene los siguientes campos: 'siteid' (ID del sitio - por ejemplo, para UK, DE, FR .. (inglés, alemán, francés. .) y 'publicado' (campo booleano, es decir, ¿el sitio está vivo o no?)

La consulta SELECT anterior obtiene todos los códigos de envío, con sus descripciones de idioma para esos sitios publicados solamente.

Ahora, también deseamos saber qué códigos de envío NO tienen descripciones en ciertos sitios. Si un código de envío es totalmente nuevo, se devolverá una fila para ese código (debido a la UNIÓN EXTERIOR IZQUIERDA). El 'scd.siteid' y 'scd.desc_frontend' serían NULL.

Sin embargo, si existe una descripción para el sitio del Reino Unido (inglés), pero la descripción para FR y DE no existe, entonces la consulta anterior simplemente devolverá UNA fila, no TRES filas. ¿Cómo puedo saber que las descripciones de DE y FR no se encuentran en un código de envío en particular?

Éstos son mis opciones:

1) Podría alguna manera de hacer esto todo dentro de una consulta. Debe haber una forma (Nunca he usado UNION, EXCEPTO, etc. antes y no estoy seguro si esto es lo que debo usar).

2) O simplemente podía hacer otra consulta a siteid SELECT site_international DONDE publicó = 't'

y lo anterior me daría todos los sitios publicados. Luego, usando PHP (que estoy usando para codificar mi sitio), para cada resultado de la consulta anterior, verificaría si faltaba alguna descripción. P.ej. La consulta de siteid anterior devolvería 3 ID (UK, DE, FR). Entonces, si solo se devuelve una fila del Reino Unido para un código de envío particular, sabría que faltan DE y FR, y podría marcar esto con mi cliente.

¿Desea avisar si existe una opción mejor "1"?

¡Muchas gracias!

Respuesta

37

Quizás no entiendo su pregunta, pero si desea obtener "entradas en una tabla que no coincida en otra tabla", puedo darle un fragmento simple.

Seleccione todas las filas de la tabla izquierda que no se encuentran en la tabla correcta.

SELECT l.* 
FROM t_left l 
LEFT JOIN t_right r 
ON  r.value = l.value 
WHERE r.value IS NULL 
+0

Creo que logré resolver esto con solo otra UNIÓN EXTERIOR IZQUIERDA. ¡Gracias por tu contribución! Tu respuesta me hizo probar algo diferente ya que tengo otras combinaciones de la izquierda, así que no necesité verificar ninguna NULL, pero en cambio quería tanto los nulos como los nulos.¡Así que uno más IZQUIERDA EXTERIOR ÚNASE a mi consulta funcionó bien! PD. ¿Alguna diferencia entre la unión izquierda y la combinación externa izquierda? – rishijd

+3

Las combinaciones izquierda, derecha y completa son uniones externas. La palabra clave "exterior" no es necesaria. –

1

Creo que esto es lo que estás buscando. El Left Join obtiene todos los pares de Código de envío y Código de sitio posibles, luego encuentra cuáles de ellos no tienen una entrada en la tabla de Descripciones. Eso es lo que hace la cláusula Exists.

SELECT  
    Shipping_Code.*, 
    Site_International.SiteID 
FROM   
    Shipping_Code 
    LEFT JOIN Site_International ON Site_International.Published = 't' 
WHERE 
    NOT EXISTS (
     SELECT 
      NULL 
     FROM 
      Shipping_Code_Description 
     WHERE 
      Shipping_Code.ShippingID = Shipping_Code_Description.ShippingID 
     AND SiteInternational.SiteID = Shipping_Code_Description.SiteID) 
Cuestiones relacionadas