查询显示表之间不匹配的记录

时间:2010-11-30 20:04:48

标签: sql sql-server tsql

我有两张桌子。一个是提交给我们的报告表。另一个是临时表,其中包含最终应提交给我们的报告记录。我想只显示临时表中与报告表中的记录不匹配的记录(因此显示仍然必须提交的报告)。

示例数据是:

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  

我尝试过LEFT OUTER JOINS,但遇到了问题。请参阅下面的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  

我的结果:

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  

对于评估1,它很有效,评估2有很多重复。我怎样才能解决这个问题才能显示出理想的结果呢?

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

5 个答案:

答案 0 :(得分:5)

当您将JOFT JOIN连接到表,然后在WHERE子句中引用该表的一个列时,您将隐式地将连接转换为INNER JOIN。相反,将这些条件移出WHERE并使它们成为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  

答案 1 :(得分:3)

您应该使用NOT EXISTS在临时表中查找提交的报告表中没有匹配条目的条目。

答案 2 :(得分:2)

此连接会将两个表中的记录相互叠加(笛卡儿),这就是为什么您会收到更多记录的原因。

请记住,您加入AssessmentId并且有多条记录具有相同的assessmentId。虽然您过滤掉那些没有相同ReportType但却遇到新组合的人。

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

答案 3 :(得分:2)

或许这样的事情?

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   

答案 4 :(得分:0)

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