mysql - 地址簿 : Turn an "at least one list suffices" query to an "all lists need to be present"

标签 mysql sql-server sqlite

我有一个 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/

相关文章:

ruby - SQLite 和 Sequel 的 boolean 值

sql - 医生、患者以及双方的联系信息

c# - 一个存储过程也可以更新整个表或单个列

用于聊天表的 mysql 引擎(堆/内存与 innodb)

mysql - 稍微复杂一点的多对多关系

mysql - 如何在sql中使用join连接两个表?

sqlite - CMake的链接器错误

javascript - 在 Electron 应用程序中使用 sql.js

php - WordPress像php mysql中的父子多级类别一样

mysql - GROUP BY - 不分组 NULL