Оператор SQL для оценки нескольких связанных таблиц - PullRequest
2 голосов
/ 07 мая 2009

У меня есть таблица Projects, в которой перечислены данные клиента. Затем у меня есть четыре связанных таблицы вакансий для работ в рамках этого проекта - Кровля, Сайдинг, Желоба и Разное. Четыре таблицы имеют поле projectID, чтобы связать их с таблицей Projects, и у всех них есть поле «status». Проект может иметь любую комбинацию заданий.

Я хочу иметь возможность выбирать только те проекты, в которых все поля статуса задания помечены как «выполненные».

Вероятно, есть простой способ сделать это, но мой мозг иногда перегревается из-за SQL.

Ответы [ 5 ]

3 голосов
/ 07 мая 2009

возможно ...:

SELECT * FROM Projects
LEFT JOIN Roofing ON (projectID)
LEFT JOIN Siding ON (projectID)
LEFT JOIN Gutters ON (projectID)
LEFT JOIN Misc ON (projectID)
WHERE (Roofing.status IS NULL OR Roofing.status="completed")
AND (Siding.status IS NULL OR Siding.status="completed")
AND (Gutters.status IS NULL OR Gutters.status="completed")
AND (Misc.status IS NULL OR Misc.status="completed")
2 голосов
/ 07 мая 2009

Подход Алекса даст вам всю информацию в одну строку (если в дочерних таблицах нет нескольких записей), но если вам это нужно, одна строка разделится на оператор объединения всех. Просто убедитесь, что вы используете одинаковые столбцы в каждом объединении. Если у вас есть данные в одной или нескольких таблицах, которых нет в других таблицах, вы бы использовали значение null в качестве значения для этого столбца в объединении.

SELECT p1.projectid,'roofing' as JobType FROM Projects p1
JOIN Roofing r ON p1.projectID = r.projectID
union all
SELECT p1.projectid,'gutters' as JobType FROM Projects p1
JOIN gutters g ON p1.projectID = g.projectID
union all
SELECT p1.projectid,'siding' as JobType FROM Projects p1
JOIN Siding s ON p1.projectID = s.projectID
union all
SELECT p1.projectid,'misc' as JobType FROM Projects p1
JOIN Misc m ON p1.projectID = m.projectID
2 голосов
/ 07 мая 2009
select p.* 
from project as p
where not exists (select 1 from roofing where projectId = p.projectId and status <> 'completed')
    and not exists (select 1 from siding where projectId = p.projectId and status <> 'completed')
    and not exists (select 1 from gutters where projectId = p.projectId and status <> 'completed')
    and not exists (select 1 from misc where projectId = p.projectId and status <> 'completed')
0 голосов
/ 07 мая 2009

Создайте представление, которое возвращает отдельные ProjectIds для «всех выполненных заданий», и присоедините его к таблице Projects. Таким образом, обновлять представление нужно только в том случае, если меняется критерий «все выполненные работы», например если новая работа добавлена. Оператор SQL для представления можно построить несколькими способами, как показано в других ответах.

0 голосов
/ 07 мая 2009
SELECT *
FROM Projects
  --Step 3: filter the projects by the results from Step2
WHERE ProjectID not in
(
  SELECT ProjectID
  FROM
  (
    --Step 1: gather all the jobs into one bucket
    SELECT ProjectID, Status
    FROM Roofing
      UNION ALL
    SELECT ProjectID, Status
    FROM Siding
      UNION ALL
    SELECT ProjectID, Status
    FROM Gutters
      UNION ALL
    SELECT ProjectID, Status
    FROM Misc
  ) as Jobs
  --Step 2: find incomplete project IDs
  GROUP BY Jobs.ProjectID
  HAVING MIN(Jobs.Status) != 'COMPLETED'
    OR MAX(Jobs.Status) != 'COMPLETED'
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...