2010-11-30 20 views
5

Tengo dos tablas. Una es una tabla de los informes que se nos han enviado. Otra es una tabla temporal con los registros de informes que eventualmente se nos deben enviar. Me gustaría mostrar solo los registros en la tabla temporal que no coinciden con los de la tabla de informes (por lo que se muestran los informes que aún deben enviarse).Consulta que muestra registros que NO coinciden entre las tablas

Ejemplo de datos es:

Reports table: 

CREATE TABLE [dbo].[Reports] 
( 
    [ReportID] [int] IDENTITY(1,1) NOT NULL, 
    [ReportDate] [date] NULL, 
    [AssessmentID] [int] NOT NULL, 
    [ReportType] [varchar](50) NULL 
); 

AssessmentID ReportType ReportID 
1 1st Quarterly 27 
2 1st Quarterly 30 
2 2nd Quarterly 31 
2 3rd Quarterly 32 

QuarterlyReportsDue table: 

CREATE TABLE #QuarterlyReportsDue 
( 
AssessmentID INT, 
InstallationDate DATE, 
QuarterlyReportType VARCHAR(50) 
); 

AssessmentID InstallationDate QuarterlyReportType 
1 2009-08-14 1st Quarterly 
1 2009-08-14 2nd Quarterly 
1 2009-08-14 3rd Quarterly 
1 2009-08-14 4th Quarterly 
2 2008-05-16 4th Quarterly 
2 2008-05-16 3rd Quarterly 
2 2008-05-16 2nd Quarterly 
2 2008-05-16 1st Quarterly 

He tratado IZQUIERDA combinaciones externas, pero estoy funcionando en problemas. Por favor, vea mi continuación de SQL:

SELECT #QuarterlyReportsDue.InstallationDate, #QuarterlyReportsDue.QuarterlyReportType, Reports.ReportType 
FROM #QuarterlyReportsDue 
LEFT OUTER JOIN Reports ON #QuarterlyReportsDue.AssessmentID = Reports.AssessmentID 
WHERE Reports.ReportType IN ('1st Quarterly', '2nd Quarterly', '3rd Quarterly', '4th Quarterly') 
AND Reports.ReportType <> #QuarterlyReportsDue.QuarterlyReportType 
ORDER BY #QuarterlyReportsDue.AssessmentID 

Y mis resultados:

AssessmentID QuarterlyReportType ReportType ReportID 
1 2nd Quarterly 1st Quarterly 27 
1 3rd Quarterly 1st Quarterly 27 
1 4th Quarterly 1st Quarterly 27 
2 4th Quarterly 1st Quarterly 30 
2 4th Quarterly 2nd Quarterly 31 
2 4th Quarterly 3rd Quarterly 32 
2 1st Quarterly 2nd Quarterly 31 
2 1st Quarterly 3rd Quarterly 32 
2 3rd Quarterly 1st Quarterly 30 
2 3rd Quarterly 2nd Quarterly 31 
2 2nd Quarterly 1st Quarterly 30 
2 2nd Quarterly 3rd Quarterly 32 

Para la evaluación 1 funciona muy bien, la evaluación 2 tiene muchos duplicados. ¿Cómo puedo evitar esto para mostrar solo los resultados ideales?

AssessmentID QuarterlyReportType ReportType 
1 2nd Quarterly 1st Quarterly 
1 3rd Quarterly 1st Quarterly 
1 4th Quarterly 1st Quarterly 
2  4th Quarterly  

Respuesta

5

Cuando combinación izquierda a una mesa y después hacer referencia a una de las columnas de esa tabla en la cláusula WHERE, que a su vez forma implícita en la unión Una unión interior. En cambio, mueva esas condiciones fuera de WHERE y haga que formen parte de las condiciones de JOIN.

SELECT q.InstallationDate, q.QuarterlyReportType, Reports.ReportType 
    FROM #QuarterlyReportsDue q 
     LEFT OUTER JOIN Reports r 
      ON q.AssessmentID = r.AssessmentID 
       AND q.QuarterlyReportType = r.ReportType 
       AND r.ReportType IN ('1st Quarterly', '2nd Quarterly', '3rd Quarterly', '4th Quarterly') 
    WHERE r.AssessmentID IS NULL /* matching record not found in Reports table */ 
    ORDER BY #QuarterlyReportsDue.AssessmentID 
+0

¡Funciona muy bien también! Gracias por la explicación. –

3

Debe utilizar NOT EXISTS para encontrar las entradas en la tabla temporal que no tienen entradas coincidentes en la tabla de los informes presentados.

+0

+1 por mencionar NO existe. – Aliostad

2

Esta unión multiplicará los registros de dos tablas entre sí (Cartesian), y es por eso que está obteniendo más registros regresando.

Recuerde que se está uniendo en AssessmentId y hay varios registros con el mismo assessmentId. Aunque está filtrando aquellos que no tienen el mismo tipo de informe pero se encuentra con nuevas combinaciones.

SELECT #QuarterlyReportsDue.InstallationDate, 
     #QuarterlyReportsDue.QuarterlyReportType 
FROM #QuarterlyReportsDue 
WHERE NOT EXISTS 
     (
     SELECT 1 
     FROM Reports 
     WHERE Reports.ReportType = QuarterlyReportsDue.QuarterlyReportType 
     AND #QuarterlyReportsDue.AssessmentID = Reports.AssessmentID 
    ) 
2

¿Algo como esto quizás?

SELECT  qrd.InstallationDate, 
      qrd.QuarterlyReportType 
FROM  #QuarterlyReportsDue qrd 
WHERE  qrd.QuarterlyReportType IN ('1st Quarterly', '2nd Quarterly', '3rd Quarterly', '4th Quarterly') 
      AND NOT EXISTS (
       SELECT 1 
       FROM  Reports r 
       WHERE r.AssessmentID = qrd.AssessmentID 
          AND r.ReportType = qrd.QuarterlyReportType 
      ) 
ORDER BY qrd.AssessmentID 
+0

Funciona perfecto. ¡Gracias! –

0
select * 
from Reports r 
left join #QuarterlyReportsDue d 
    on d.AssessmentID=r.AssessmentID 
    and d.QuarterlyReportType=ReportType 
where d.AssessmentID is null 
Cuestiones relacionadas