我有3张桌子:
1)运动:exercise_id,名称
2)设备:equipment_id,名称
3)exercise_equipment:exercise_id,equipment_id - 这是练习和装备之间的链接表。在此表中,一项练习可能需要多件设备,并且相同的设备可用于许多练习。
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)
;
我需要做的是选择用户可以使用他所拥有的设备进行的所有练习(例如,1和2 - 没有设备或垫子)。
我找到了一些示例,并尝试使用内部联接进行以下查询,其中包含:
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));
但是他们会返回所有练习,而不仅仅是前三个练习。在这种情况下,如果用户想要进行不需要任何设备或垫子的练习(1和2),我想要返回俯卧撑,仰卧起坐和深蹲,而不是用球进行垫练习。
我希望我的解释清楚。我真的很感激我能得到的任何帮助!
答案 0 :(得分:0)
您希望练习仅使用 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;