SQL - 复杂查询LEFT JOIN与WHERE

时间:2016-05-17 03:03:57

标签: sql sql-server join

下面的查询是我遇到错误的查询的简化版本,下面显示的这个较小的查询之前有一个where子句,它实际上使我的左连接无效。

SELECT FC_Name, COUNT(F.Findings_ID) AS 'No_of_Findings'
FROM FindingCategories AS FC
LEFT OUTER JOIN Findingsubcategories AS FSC ON FSC.FC_ID = FC.FC_ID
LEFT OUTER JOIN Findings AS F ON F.FSC_ID = FSC.FSC_ID AND F.AU_ID = @Audit_ID
LEFT OUTER JOIN Audit AS A ON A.Audit_ID = F.AU_ID 
GROUP BY FC_Name

现在 - 遗憾的是我无法使用此查询来实现我的目标,完成: 我需要在数据库中获取当前选择的详细信息以及上一年的值。如下所示:

SELECT A.Audit_ID, c.FC_Name, COUNT(c.FC_Name) AS 'No_of_Findings'
FROM Audit AS A
  LEFT OUTER JOIN Findings F on A.Audit_ID = f.AU_ID
  LEFT OUTER JOIN FindingCategories C on C.FC_ID = F.Findings_category_ID
  LEFT OUTER JOIN GovernmentAgencies GA on GA.GA_ID = A.GA_ID
  LEFT OUTER JOIN AuditType AT on AT.AuditType_ID = a.AuditType_ID 
WHERE A.Audit_Year= @Year AND (@Agency IS NULL OR ga.GA_LegalName = @Agency)
                           AND (@AuditType is null or @AuditType = AT.AuditType_Category)
                           AND (@Audit_ID is null or @Audit_ID  = a.Audit_ID)
GROUP BY A.Audit_Year, c.FC_Name, A.Audit_ID

SELECT a.Audit_ID, c.FC_Name, COUNT(c.FC_Name) AS 'No_of_Findings'
FROM Audit AS A
  LEFT OUTER JOIN Findings F on a.Audit_ID = f.AU_ID
  LEFT OUTER JOIN FindingCategories C on C.FC_ID = F.Findings_category_ID
  LEFT OUTER JOIN GovernmentAgencies GA on GA.GA_ID = a.GA_ID
  LEFT OUTER JOIN AuditType AT on AT.AuditType_ID = a.AuditType_ID
WHERE a.Audit_Year= '@Year-1 AND (@Agency IS NULL OR ga.GA_LegalName = @Agency)
                           AND (@AuditType is null or @AuditType = AT.AuditType_Category)
GROUP BY a.Audit_Year, c.FC_Name, a.Audit_ID

再次,根据我的第一个查询,我意识到我的WHERE将我的左连接转变为内连接,但我尝试了几种不同的方法来解决这个问题无济于事。如何更改此问题以解决问题?

示例数据: 表1 /表2

enter image description here

表1应该是什么样的 - 使用更简单的查询:

enter image description here

2 个答案:

答案 0 :(得分:2)

尝试将WHERE子句中的条件放到ON子句中:

SELECT 
    a.Audit_ID, 
    c.FC_Name, 
    COUNT(c.FC_Name) AS 'No_of_Findings'
FROM Audit AS A
LEFT OUTER JOIN Findings F 
    ON a.Audit_ID = f.AU_ID
LEFT OUTER JOIN FindingCategories C 
    ON C.FC_ID = F.Findings_category_ID
LEFT OUTER JOIN GovernmentAgencies GA 
    ON GA.GA_ID = a.GA_ID
    AND (@Agency IS NULL OR ga.GA_LegalName = @Agency)
LEFT OUTER JOIN AuditType AT 
    ON AT.AuditType_ID = a.AuditType_ID
    AND AT.Audit_Year = @Year - 1
    AND (@AuditType IS NULL OR @AuditType = AT.AuditType_Category)
GROUP BY a.Audit_Year, c.FC_Name, a.Audit_ID

答案 1 :(得分:0)

  1. 这两年可能会将它们合并为一个查询。
  2. 使用CTE或子查询将过滤器应用于正确的结果集。
  3. 在可以为空的参数上使用ISNULL。
  4. WITH CTE AS (SELECT A.Audit_ID, A.Audit_Year, c.FC_Name, ga.GA_LegalName, AT.AuditType_Category, COUNT(c.FC_Name) AS 'No_of_Findings' FROM Audit AS A LEFT OUTER JOIN Findings F ON A.Audit_ID = f.AU_ID LEFT OUTER JOIN FindingCategories C ON C.FC_ID = F.Findings_category_ID LEFT OUTER JOIN GovernmentAgencies GA ON GA.GA_ID = A.GA_ID LEFT OUTER JOIN AuditType AT ON AT.AuditType_ID = a.AuditType_ID WHERE A.Audit_Year IN (@Year, @Year - 1) GROUP BY A.Audit_Year, c.FC_Name, ga.GA_LegalName, AT.AuditType_Category, A.Audit_ID) SELECT Audit_ID, Audit_Year, FC_Name, No_of_Findings FROM CTE WHERE GA_LegalName = ISNULL(@Agency, GA_LegalName) AND AuditType_Category = ISNULL(@AuditType, AuditType_Category) AND Audit_ID = ISNULL(@Audit_ID, Audit_ID);

相关问题