2011-08-03 56 views
1

我使用MSSQL Server 2008的 我有三個表如下:MSSQL嵌套查詢上一列中不同

表:項目 列:專案編號,{主鍵} ProjectNickName,BusinessType

表:審計 列:{外鍵} ProjectNickName,{主鍵} AuditID,AuditCreationDate,AuditStatus

表:調查結果 列:{外鍵} AuditID,FindingStatus,{主鍵} FindingNumber

項目來審覈:一對多

審計,以調查結果:一對多

我想找到的所有審覈記錄審計狀態爲「開放」,沒有發現「開放」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,它解決了這個問題,但是審計記錄仍然會顯示是否至少有一個發現沒有'Open'發現狀態,另一個發現與審計有關,DID有'Open'發現狀態。 如前所述,我只希望審計沒有發現記錄,並在結果集中顯示「Open」的查找狀態。

我在猜測我可能需要使用某種嵌套查詢與不同的功能,但我不能包裝我的頭腦如何做到這一點呢。

任何幫助非常感謝!我試圖儘可能清晰和準確,但讓我知道我是否可以詳細說明任何事情。

回答

2
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 
+0

會返回多個行的審計與多個關閉查找 – Andomar

+0

不,它不會!因爲我只在發現狀態等於'OPEN'並且只有左連接爲空的情況下才加入! – ingo

+0

閱讀代碼的最後一行... – ingo

1

您可以使用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' 
     ) 
+0

我認爲這也會起作用。 – deutschZuid

+0

這將比我的解決方案表現更好,因爲在這裏您可以利用索引。我的解決方案可能總是做一個哈希連接,然後過濾,所以我會upvote它。是的Andomar我的解決方案也可以工作..我用了很多次:) – ingo

+0

這工作!非常感謝你和Ingo的指導:D – sgerhardt

0

您可能可以使用相關的子查詢,例如這個。

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

這應該禁止有發現有任何狀況審覈=「打開」

你需要與你的項目要完成其加入,等等。

0

如果審計在所有調查結果表中都沒有行(即,將用左外部聯接返回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') 
+0

是的,如果根本沒有發現,仍然會顯示。 – sgerhardt

+0

是的..我用這個假設編輯了你的查詢。這對你有用嗎? – deutschZuid

+0

明天我會找到我的工作電腦。感謝你和其他人提供有用的信息和迴應。 :d – sgerhardt