You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL多对多关系查询:如何获取参与全部旅行的员工?

嘿,这个问题是SQL里挺经典的「全域匹配」场景,我来给你分享几种实际项目里常用的解法,每种都给你讲清思路和代码:

方法1:通过计数匹配总旅行数

思路很直接:先算出系统里总共有多少个旅行,再统计每个员工参与的旅行数量,只要这个数量等于总旅行数,就说明该员工参加了所有旅行。

如果employee_tour里没有重复报名的记录(同一个员工不会多次报同一个旅行),可以用这个SQL:

SELECT e.employee_id, e.employee_name
FROM employee e
JOIN employee_tour et ON e.employee_id = et.employee_id
GROUP BY e.employee_id, e.employee_name
HAVING COUNT(et.tour_id) = (SELECT COUNT(*) FROM tour);

要是employee_tour可能存在重复记录(比如员工误操作重复报名),那得用COUNT(DISTINCT)去重,避免统计数虚高:

SELECT e.employee_id, e.employee_name
FROM employee e
JOIN employee_tour et ON e.employee_id = et.employee_id
GROUP BY e.employee_id, e.employee_name
HAVING COUNT(DISTINCT et.tour_id) = (SELECT COUNT(*) FROM tour);
方法2:用NOT EXISTS做反证法

换个角度想:不存在任何一个旅行是该员工没参加的,那这个员工就符合要求。这种反证法的思路在大数据量场景下往往更高效,因为NOT EXISTS会用到短路判断,不用全量统计。

对应的SQL是:

SELECT e.employee_id, e.employee_name
FROM employee e
WHERE NOT EXISTS (
    -- 找这个员工没参加的旅行
    SELECT 1 FROM tour t
    WHERE NOT EXISTS (
        SELECT 1 FROM employee_tour et
        WHERE et.employee_id = e.employee_id 
          AND et.tour_id = t.tour_id
    )
);
小提醒
  • 如果tour表可能存在无效旅行(比如已取消的),记得在子查询里加过滤条件,比如SELECT COUNT(*) FROM tour WHERE is_active = 1
  • 两种方法都要确保employee_tour里的tour_id和employee_id都是有效的外键,避免脏数据影响结果

内容的提问来源于stack exchange,提问作者jonny thach

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:13:29