Как связать два значения во вложенном запросе SQL SELECT? - PullRequest
3 голосов
/ 27 апреля 2011

У меня есть SQL Server таблицы JobFiles со столбцами JobId и FileId. Эта таблица отображает, какой файл принадлежит какому заданию. Каждое задание может «содержать» один или несколько файлов, и каждый файл может «содержаться» в одном или нескольких заданиях. Для каждой пары, в которой задание M содержит файл N, в таблице есть строка (M, N).

Я начинаю с идентификатора задания, и мне нужно получить список всех файлов, чтобы они принадлежали только этому заданию. Мне трудно написать запрос на это. До сих пор я создал следующее (псевдокод):

SELECT FileId FROM JobFiles WHERE JobId=JobIdICareAbout AND NOT EXISTS
    (SELECT * FROM JobFiles WHERE FileId=ThatSameFileId AND JobId<>JobIdICareAbout);

Я верю, что вышеприведенное сработает, но у меня есть проблема с отображением ThatSameFileId на FileId, возвращаемое из внешнего SELECT, чтобы база данных знала, что они одинаковы.

Как мне это сделать? Как мне сказать базе данных, что FileId во внешнем SELECT должен быть равен FileId во внутреннем SELECT?

Ответы [ 4 ]

3 голосов
/ 27 апреля 2011

Я использую другой подход, но если бы я правильно понял вашу проблему, это привело бы к нужному вам результату.

Суть этого выглядит следующим образом

  • Получить все FileId's из JobId вы заботитесь о
  • JOIN назад с JobFiles tabel
  • Оставьте только те FileId's, которые не имеют других JobId, используя HAVING

Оператор SQL

SELECT  jf1.FileId
FROM    JobFiles jf1
        INNER JOIN (
          SELECT FileId
          FROM   JobFiles
          WHERE  JobID = JobIdICareAbout
        ) jf2 ON jf2.FileID = jf1.FileID
GROUP BY
        jf1.FileId
HAVING COUNT(*) = 1
3 голосов
/ 27 апреля 2011

Как насчет использования NOT IN:

SELECT FileId FROM JobFiles WHERE JobId=JobIdICareAbout AND FileID NOT IN
    (SELECT FileId FROM JobFiles WHERE JobId<>JobIdICareAbout);

И небольшое изменение на этом:

SELECT FileId FROM JobFiles WHERE JobId=JobIdICareAbout
EXCEPT
SELECT FileId FROM JobFiles WHERE JobId<>JobIdICareAbout
2 голосов
/ 27 апреля 2011

Кажется, у вас много (разных, но) рабочих ответов / запросов. Вот еще один пример использования NOT EXISTS. Это только исправление того, что вы пытались:

SELECT jf.FileId
FROM JobFiles jf 
WHERE jf.JobId = JobIdICareAbout
  AND NOT EXISTS
    ( SELECT 1
      FROM JobFiles jf2
      WHERE jf2.FileId = jf.FileId 
        AND jf2.JobId <> JobIdICareAbout
    )
2 голосов
/ 27 апреля 2011

Другой подход:
LEFT JOIN только найдет строки, если этот файл связан с другим заданием, проверка на IS NULL удаляет эти файлы:

SELECT JobFiles.FileId
FROM JobFiles
LEFT JOIN JobFiles OtherJobFiles ON (     OtherJobFiles.FileId = JobFiles.FileId
                                      AND OtherJobFiles.JobId <> JobIdICareAbout )
WHERE JobFiles.JobId=JobIdICareAbout
  AND OtherJobFiles.FileId IS NULL
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...