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;
我有 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;