我有一个 SQLite3 数据库,其中包含以下五个表: Addressbook SQL Schema
列表可以分配给联系人和打印作业。如果我想处理打印作业(例如在信封上打印联系人),我需要获取与该打印作业分配相同列表的所有联系人。
到目前为止,我得到了这个 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`
我将其视为“至少一个列表就足够了”,但我需要一个“所有列表也需要分配给一项工作”。
这样的查询是什么样的?
编辑:
以下是一些生成示例数据的查询:SQL Sample Data
以下是每个打印作业的预期结果:
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
最佳答案
听起来目标是为每个联系人打印一个信封(省钱,保护环境,耶!);本质上是对列表进行重复数据删除。一个想法是将“复合作业”(如作业 3)转变为它自己的实体。一种方法是使用虚拟表,如下所示:
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 job_id,contact_id,jlist,clist
from flattenJob
JOIN flattenCont on jlist = clist
这是示例数据的结果:
job_id contact_id jlist clist
---------- ---------- ---------- ----------
1 1 1 1
1 2 1 1
1 3 1 1
2 5 2 2
3 4 1,2 1,2
3 6 1,2 1,2
这应该为您创建成功的查询提供一个良好的起点。
关于mysql - 地址簿 : Turn an "at least one list suffices" query to an "all lists need to be present",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55825092/