SQL объединяет три таблицы; возвращает значения из таблицы 1, где все экземпляры в таблице 2 имеют одинаковое значение поля

#sql #inner-join #aggregate-functions #having-clause

#sql #внутреннее соединение #агрегатные функции #наличие-предложения

Вопрос:

У меня есть три таблицы, которые мне нужно объединить. В частности, таблица 1 должна быть присоединена к таблице 2, а таблица 2 — к таблице 3. Мне нужно вернуть значения из таблицы 1, где все экземпляры значений, выбранных в таблице 1 в таблице 2, имеют поле с некоторым значением, а затем дополнительно выбираются моим объединением в таблице 3. Возможно, будет проще представить пример.

Таблица 1

Порядок Статус
001 A
002 A
003 B
004 B
005 A

Таблица 2

Поле Статус Порядок Пересылка
1 X 001 1
2 X 001 2
3 X 002 1
4 X 003 2
5 X 003 2
6 Y 004 1
7 X 004 2
8 X 004 1
9 Y 005 1

Таблица 3

Пересылка Статус
1 C
2 A

Мне нужно выбрать все заказы из таблицы 1, которые имеют статус «A» И привязаны к ячейкам в таблице 2, где все ячейки для заказа имеют статус «X» и привязаны к отгрузке в таблице 3, которая имеет статус «C».

Мой конечный результат должен возвращать следующее:

Порядок
002

У меня есть следующее, но оно не является точным на 100%, так как Table2.Отгрузка может быть пустым значением. Моей реальной проблемой является сложность поиска заказов из таблицы1, где все поля для этого заказа в таблице 2 имеют одинаковый статус.

 SELECT order
FROM table1
JOIN table2 ON table1.order = table2.order
WHERE table2.order NOT IN
(SELECT table2.order FROM table2
JOIN table3 ON table2.shipment=table3.shipment
WHERE table3.status = 'A')
AND table2.order IN
(SELECT table2.order FROM table2
JOIN table3 ON table2.order = table3.order
WHERE table3.status = 'C') 
AND table1.status = 'A'
AND table2.status = 'X'

                                                             
 

Ответ №1:

Вы можете использовать агрегирование и фильтровать по t2 и t3 с предложением having:

 select t1.orderid
from table1 t1
inner join table2 t2 on t2.orderid  = t1.orderid
inner join table3 t3 on t3.shipment = t2.shipment
where t1.status = 'A'
group by t1.orderid
having max(case when t2.status <> 'X' then 1 else 0 end) = 0 
   and max(case when t3.status <> 'C' then 1 else 0 end) = 0
 

Комментарии:

1. Спасибо! Это сработало великолепно, оцените и быстрый ответ!