MYSQL:select 来自多对多链接 table

MYSQL: select from many-to-many linking table

我有 3 个 table:

1)练习:exercise_id,姓名

2) 装备:equipment_id,姓名

3) exercise_equipment: exercise_id, equipment_id - 这是运动与装备之间的联系table。在这个table中,一个练习可以需要多件装备,同样的装备可以用于很多练习。

CREATE TABLE exercise
    (`ex_id` int, `name` varchar(30))
;   
INSERT INTO exercise
    (`ex_id`, `name`)
VALUES
    (1, 'push ups'),
    (2, 'sit ups'),
    (3, 'squats'),
    (4, 'push ups with a fitness ball')
;

CREATE TABLE equipment
    (`eq_id` int, `name` varchar(30))
;
INSERT INTO equipment
    (`eq_id`, `name`)
VALUES
    (1, 'none'),
    (2, 'mat'),
    (3, 'ball')
;

CREATE TABLE exercise_equipment
    (`ex_id` int, `eq_id` int)
;
INSERT INTO exercise_equipment
    (`ex_id`, `eq_id`)
VALUES
    (1, 2),
    (2, 2),
    (3, 1),
    (4, 2),
    (4, 3)
;

我需要做的是 select 用户可以使用他拥有的设备进行的所有练习(例如,1 和 2 - 没有设备或垫子)。

我找到了一些示例并尝试了以下使用内部连接和 where in 的查询:

SELECT ex.ex_id, ex.name from exercise ex 
LEFT JOIN exercise_equipment exeq ON ex.ex_id = exeq.ex_id 
WHERE exeq.eq_id IN (1,2);

select ex_id, name from exercise 
where ex_id in (select ex_id from exercise_equipment where eq_id in (1,2));

但是他们 return 所有练习,而不仅仅是前三个。在这种情况下,如果用户想要进行不需要设备或垫子(1 和 2)的锻炼,我希望进行俯卧撑、仰卧起坐和下蹲 returned,而不是垫子锻炼球。

希望我的解释清楚。如果能得到任何帮助,我将不胜感激!

您想要使用 1 和 2 的练习。当您使用 WHERE 子句时,您将过滤掉所有其他设备,因此不会工作。

相反,您需要汇总并检查整个练习是否没有使用其他设备。这是一个类似的查询,带有 HAVING 子句:

SELECT ex.ex_id, ex.name
FROM exercise ex LEFT JOIN
     exercise_equipment exeq
     ON ex.ex_id = exeq.ex_id 
GROUP BY ex.ex_id, ex.name
HAVING SUM(exeq.eq_id NOT IN (1, 2)) = 0;

如果有些练习根本没有设备,您可能需要:

HAVING COALESCE(SUM(exeq.eq_id NOT IN (1, 2)), 0) = 0;