Вложенный запрос MSSQL на одной колонке - PullRequest
1 голос
/ 03 августа 2011

Я использую MSSQL Server 2008. У меня есть три таблицы следующим образом:

Таблица: Project Столбцы: ProjectID, {Primary Key} ProjectNickName, BusinessType

Таблица: Аудит Столбцы: {внешний ключ} ProjectNickName, {первичный ключ} AuditID, AuditCreationDate, AuditStatus

Таблица: Результаты Столбцы: {Внешний ключ} AuditID, FindingStatus, {Первичный ключ} FindingNumber

Проект для аудита: один ко многим

Аудит результатов: один ко многим

Я хочу найти все записи аудита с AuditStatus «Open», которые не имеют результатов с «Open» FindingStatus. Кроме того, запись аудита должна быть связана с проектом, для которого BusinessType имеет значение «Внешний», а 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 только для одного столбца , который решил эту проблему, но контрольная запись все равно показала бы, если бы был хотя бы один результат, у которого не было «Open» FindStatus, а другой результат, связанный с аудит, который ДЕЙСТВИТЕЛЬНО имеет 'Открытый' findStatus. Как упоминалось ранее, я хочу, чтобы в моем наборе результатов отображались только те аудиты, у которых нет записей о поиске с FindStatus 'Open'.

Полагаю, мне может понадобиться использовать какой-то вложенный запрос с отдельной функцией, но я пока не могу понять, как это сделать.

Любая помощь очень ценится! Я старался быть как можно более ясным и точным, но дайте мне знать, если смогу что-нибудь уточнить.

Ответы [ 4 ]

2 голосов
/ 03 августа 2011
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
1 голос
/ 03 августа 2011

Вы можете использовать подзапрос 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 голосов
/ 03 августа 2011

Вы не указали, нужно ли отображать строку, если у аудита вообще нет строки в таблице результатов (т.е. будет возвращаться ноль с левым внешним соединением)Предполагая, что вы действительно хотите, чтобы они показали, вот один из способов сделать это.

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 голосов
/ 03 августа 2011

Возможно, вы сможете использовать коррелированный подзапрос, такой как этот.

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

Который должен запретить любые проверки, которые имеют результаты со статусом = 'Open'

Вам нужно будет завершить его с помощью вашего Project JOIN и так далее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...