【问题标题】:MSSQL Nested Query Distinct on One ColumnMSSQL 嵌套查询在一列上不同
【发布时间】:2011-08-03 01:54:36
【问题描述】:

我使用的是 MSSQL Server 2008。 我有如下三个表:

表:项目 列:ProjectID、{Primary Key} ProjectNickName、BusinessType

表格:审核 列:{Foreign Key}ProjectNickName、{Primary Key}AuditID、AuditCreationDate、AuditStatus

表格:调查结果 列:{Foreign Key}AuditID、FindingStatus、{Primary Key}FindingNumber

要审计的项目:一对多

审计结果:一对多

我想查找所有 AuditStatus 为“Open”且没有任何结果为“Open”FindingStatus 的审计记录。此外,审计记录必须与 BusinessType 为“External”且 AuditCreationDate 在过去 30 天内的项目相关联。


这是我目前所拥有的:

Select a.AuditID, p.BusinessType, p.ProjectNickName, a.AuditCreationDate 
FROM Project p 
INNER JOIN Audit a ON p.ProjectNickName = a.ProjectNickName 
LEFT OUTER JOIN Findings f on a.AuditID = f.AuditID 
WHERE p.BusinessType LIKE 'External' AND AuditCreationDate >= GETDATE()-30 
      AND a.AuditStatus LIKE 'OPEN' and f.FindingStatus NOT LIKE 'OPEN'

上面的查询有两个问题。

  1. 每次审核可能有多个结果,但如果其中任何一个结果的状态为“未决”,我不希望显示该记录。
  2. 上面没有显示不同的审计记录。如果审核的多个结果不是“打开”状态,它将显示出来。我只想要不同的审计记录。我查看了以下DISTINCT for only one Column,它解决了该问题,但审核记录仍会显示是否至少有一个发现没有“打开”findingStatus 和另一个与 DID 有“打开”的审核相关的发现' 发现状态。 如前所述,我只希望没有结果记录且结果状态为“打开”的审核出现在我的结果集中。

我猜我可能需要使用某种具有独特功能的嵌套查询,但我现在还想不通如何去做。

非常感谢任何帮助!我尽量做到清晰和准确,但如果我能详细说明,请告诉我。

【问题讨论】:

    标签: sql-server sql-server-2008 nested


    【解决方案1】:
    Select 
        a.AuditID, 
        p.BusinessType, 
        p.ProjectNickName, 
        a.AuditCreationDate 
    FROM 
        Project p 
    JOIN 
        Audit a 
        ON p.ProjectNickName = a.ProjectNickName AND
        a.AuditCreationDate >= GETDATE()-30 AND 
        a.AuditStatus ='OPEN'
    LEFT JOIN 
        Findings f 
        on  a.AuditID = f.AuditID and
            f.FindingStatus ='OPEN'
    WHERE 
        p.BusinessType ='External' AND      
        f.FindingStatus is null -- Here we could use any column name from the findings table. We are basically saying we don't want there to exist an associated findings entry that has the findingStatus open
    

    【讨论】:

    • 将返回多行以进行具有多个已关闭结果的审计
    • 不,不会!因为我只有在 findstatus 等于 'OPEN' 并且只有左连接为空的情况下才加入!
    • @ingo:有趣,+1。查询优化器足够聪明,可以看到这相当于not exists,所以我不确定哪个会更好
    • @Andomar:我不知道。谢谢你的信息:)
    【解决方案2】:

    您可以使用not exists 子查询来排除具有未决结果的审计。这也将消除每次审计的多行,因为您不再加入结果表。

    select  a.AuditID
    ,       p.BusinessType
    ,       p.ProjectNickName
    ,       a.AuditCreationDate 
    from    Project p 
    join    Audit a 
    on      p.ProjectNickName = a.ProjectNickName 
    where   p.BusinessType LIKE 'External' and 
            a.AuditStatus LIKE 'OPEN' and
            a.AuditCreationDate >= getdate()-30 and 
            not exists
            (
            select  *
            from    Findings f 
            where   a.AuditID = f.AuditID and
                    f.FindingStatus = 'OPEN'
            )
    

    【讨论】:

    • 这可能会比我的解决方案执行得更好,因为在这里您可以利用索引。我的解决方案可能总是做一个哈希连接然后过滤,所以我会赞成它。是的,Andomar 我的解决方案也可以工作..我已经使用过很多次了 :)
    • 这成功了!非常感谢您和 Ingo 的指导:D
    【解决方案3】:

    您也许可以使用相关子查询,例如这个。

    SELECT * FROM Audit A WHERE AuditID NOT IN 
    (SELECT AuditID FROM Findings 
    WHERE AuditID = A.AuditID and Status = 'OPEN')
    

    这应该禁止任何具有 Status = 'Open' 调查结果的审计

    您需要通过 Project JOIN 等来完成它。

    【讨论】:

      【解决方案4】:

      如果审核在结果表中根本没有行(即,将使用左外连接返回 null),您没有指定是否有必要显示该行。假设您确实希望它们显示,这是一种方法。

      Select a.AuditID, p.BusinessType, p.ProjectNickName, a.AuditCreationDate 
      FROM Project p 
      INNER JOIN Audit a ON p.ProjectNickName = a.ProjectNickName 
      WHERE p.BusinessType LIKE 'External' 
      AND AuditCreationDate >= GETDATE()-30 
      AND a.AuditStatus LIKE 'OPEN' 
      AND a.AuditID NOT IN
      (select distinct AuditID from Findings
        where FindingStatus LIKE 'OPEN')
      

      【讨论】:

      • 是的。我根据这个假设编辑了您的查询。那么这对你有用吗?
      • 明天我会在我的工作电脑前找到答案。感谢您和其他所有人的帮助和信息丰富的回复。 :D
      猜你喜欢
      • 1970-01-01
      • 2013-07-13
      • 1970-01-01
      • 2018-01-05
      • 1970-01-01
      • 1970-01-01
      • 2016-04-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多