Pregunta

Tengo dos tablas de la siguiente manera:

tblCountry (countryID, countryCode)

tblProjectCountry(ProjectID, countryID)

La tabla tblCountry es una lista de todos los países con sus códigos y los asociados de mesa tblProjectCountry ciertos países con determinados proyectos. Necesito una sentencia SQL que me da una lista de los países con su código de país que no tienen asociado un registro en la tabla tblProjectCountry. hasta el momento que llegué a aquí:

SELECT     tblCountry.countryID, tblCountry.countryCode
FROM         tblProjectCountry INNER JOIN
                      tblCountry ON tblProjectCountry.countryID = tblCountry.countryID
WHERE     (SELECT     COUNT(ProjectID)
                         FROM         tblProjectCountry 
                         WHERE     (ProjectID = 1) AND (countryID = tblCountry.countryID)) = 0

La declaración anterior analiza como correcta, pero no dan el resultado exacto que estoy buscando. ¿Alguien puede ayudar?

¿Fue útil?

Solución

¿Esto funciona?

SELECT countryID, countryCode 
  FROM tblCountry 
  WHERE countryID NOT IN ( SELECT countryID FROM tblProjectCountry )

Otros consejos

Otra alternativa:

SELECT outerTbl.countryID, outerTbl.countryCode 
    FROM tblCountry AS outerTbl
    WHERE NOT EXISTS 
        (
            SELECT countryID FROM tblProjectCountry WHERE countryID = outerTbl.countryID
        )

Esta utiliza lo que se llama un subconsulta correlacionada

Tenga en cuenta que también hacen uso de la EXISTE palabra clave ( véase también )

En SQL Server, NO existe es generalmente piensa que es más performante . Por otra RDMS su kilometraje puede variar .

Hay, al menos, dos maneras de encontrar los registros no asociados.

1. Usando LEFT JOIN

SELECT DISTINCT -- each country only once
  tblCountry.countryID,
  tblCountry.tblCountry 
FROM
  tblCountry 
  LEFT JOIN
    tblProjectCountry
  ON
    tblProjectCountry.countryID = tblCountry.countryID
WHERE
  tblProjectCountry.ProjectID IS NULL -- get only records with no pair in projects table
ORDER BY
  tblCountry.countryID

erikkallen mencionado esto podría no realizar bien .

2. Usando NOT EXISTS

Varios versión de utilizar NOT EXISTS o IN fueron sugeridas por rohancragg y otros:

SELECT
  tblCountry.countryID,
  tblCountry.tblCountry 
FROM
  tblCountry 
WHERE
  -- get only records with no pair in projects table
  NOT EXISTS (SELECT TOP 1 1 FROM tblProjectCountry WHERE tblProjectCountry.countryID = tblCountry.countryID) 
ORDER BY
  tblCountry.countryID

depende de su DBMS y tamaño de los países y los proyectos de tablas de ambos versión podría obtener mejores resultados.

En mi prueba en MS SQL 2005 no hubo una diferencia significativa entre la primera y la segunda consulta de mesa con ~ 250 países y ~ 5000 proyectos . Sin embargo en la mesa con más de 3M proyectos segunda versión (usando NOT EXISTS) realizado mucho, mucho mejor.

Así que, como siempre, vale la pena comprobar ambas versiones.

SELECT ... DONDE ID NO IN (SELECT ...)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top