У меня есть база данных SQLite3, которая содержит, среди прочего, следующие пять таблиц:
Схема адресной книги SQL
Списки могут быть назначены контактам и заданиям на печать. Если я хочу обработать задание на печать (например, печать контактов на конвертах), мне нужно выбрать все те контакты, которым назначены те же списки, что и для этого задания на печать.
Пока что я получил этот SQL-запрос, но он выбирает все контакты, у которых как минимум один общий список для рассматриваемого задания на печать, но мне нужно все назначенные списки для матч:
SELECT DISTINCT `contact`.* FROM `contact` JOIN (
SELECT `contact_id` FROM `contact_list` JOIN (
SELECT `list_id` FROM `job_list` WHERE `job_id` = :id
) AS `inner` ON `inner`.`list_id` = `contact_list`.`list_id`
) AS `outer` ON `outer`.`contact_id` = `contact`.`id`
Я рассматриваю это как «хотя бы один список достаточно хорош», но мне нужно «все списки должны быть назначены и для работы».
Как выглядит такой запрос?
Edit:
Вот некоторые запросы, которые генерируют пример данных: Пример данных SQL
А вот ожидаемые результаты для каждого задания на печать:
job_id contact_id
1 1, 2, 3
2 5
3 4, 6
Контакт 7 никогда не должен появляться
Результат
SELECT * FROM contact WHERE id IN (
WITH flattenJob (job_id, jlist) AS (
SELECT job_id, group_concat(list_id)
FROM job_list
GROUP BY job_id
),
flattenCont (contact_id, clist) AS (
SELECT contact_id, group_concat(list_id)
FROM contact_list
GROUP BY contact_id
)
SELECT contact_id
FROM flattenJob
JOIN flattenCont ON jlist = clist
WHERE job_id = :id
)
ORDER BY name