Гипотетическая ситуация: я работаю в компании по изготовлению нестандартных вывесок, и некоторые из наших клиентов представили больше дизайнов вывесок, чем используют в настоящее время. Я хочу знать, какие знаки никогда не использовались.
3 таблицы:
Таблица A - знаки для компании
sign_pk (уникальный) | company_pk | sign_description
1 -------------------- 1 ---------------- маленький
2 -------------------- 1 ---------------- большой
3 -------------------- 2 ---------------- средний
4 -------------------- 2 ---------------- jumbo
5 -------------------- 3 ---------------- баннер
Таблица B - местонахождение компании
company_pk | company_location (уникальный)
1 ------ | ------ 987
1 ------ | ------ 876
2 ------ | ------ 456
2 ------ | ------ 123
таблица C - знаки в местах (это немного натянуто, но в каждом ряду может быть 2 знака, и это отношение один ко многим от местоположения компании до знаков в местах)
company_location | front_sign | back_sign
987 ------------ 1 ------------ 2
987 ------------ 2 ------------ 1
876 ------------ 2 ------------ 1
456 ------------ 3 ------------ 4
123 ------------ 4 ------------ 3
Итак, a.company_pk = b.company_pk и b.company_location = c.company_location. То, что я хочу попытаться найти, это как запросить и получить обратно, что sign_pk 5 не находится ни в каком месте. Запросить каждый sign_pk для всех значений front_sign и back_sign немного нецелесообразно, поскольку во всех таблицах миллионы строк. Таблица a проиндексирована для sign_pk и company_pk, таблица b - для обоих полей, а таблица c - только для местоположений компании. Я пытаюсь написать это по принципу «каждый знак принадлежит компании, поэтому найдите знаки, которые не являются передним или задним знаком в любом месте, принадлежащем компании, связанной с этим знаком».
Мой первоначальный план был:
Select a.sign_pk<br>
from a, b, c<br>
where a.company_pk = b.company_pk<br>
and b.company_location = c.company_location<br>
and a.sign_pk *= c.front_sign<br>
group by a.sign_pk having count(c.front_sign) = 0
просто чтобы сделать передний знак, а затем повторить для заднего, но это не сработает, потому что c является внутренним членом внешнего соединения, а также внутреннего соединения.
Все это довольно запутанно, но если кто-то сможет понять это, я буду вашим лучшим другом.