MySQL查询:筛选GROUP_CONCAT结果不含指定值的记录
搞定MySQL查询:找出未使用指定器材的训练动作
没问题,我来帮你解决这个需求!首先咱们理清楚场景:你有训练动作表exercises,还有记录器材关联的表(我暂时叫它exercise_equipment,如果实际表名不一样你替换就行),要找出那些没用到某个指定器材的训练动作——也就是指定的EquipmentId不在该动作的GROUP_CONCAT结果里。
第一种写法:用GROUP_CONCAT + FIND_IN_SET
假设咱们要找没使用EquipmentId=2的动作,直接看代码:
SELECT e.id, e.ExerciseName, GROUP_CONCAT(ee.EquipmentId SEPARATOR ',') AS 已用器材ID列表 FROM exercises e LEFT JOIN exercise_equipment ee ON e.id = ee.ExerciseId GROUP BY e.id, e.ExerciseName HAVING NOT FIND_IN_SET('2', 已用器材ID列表)
为啥这么写?
LEFT JOIN是关键:哪怕某个动作完全没用到任何器材,也能被查出来,不会漏掉;GROUP_CONCAT把每个动作对应的所有器材ID拼成逗号分隔的字符串,方便后续检查;FIND_IN_SET('2', 已用器材ID列表)会判断指定的器材ID是不是在这个字符串里,加个NOT就得到了没用到该器材的动作。
第二种更高效的写法:不用字符串拼接
如果你的数据量比较大,字符串拼接可能有额外开销,那可以用子查询实现,逻辑更直接:
SELECT id, ExerciseName FROM exercises WHERE id NOT IN ( SELECT DISTINCT ExerciseId FROM exercise_equipment WHERE EquipmentId = '2' )
这个思路就是:先找出所有用到了指定器材的动作ID,然后从训练动作表里排除这些ID,剩下的就是没用到该器材的动作。
注意点
- 如果你的关联表实际名字不是
exercise_equipment,记得替换成真实表名; - 把语句里的
'2'换成你实际要指定的EquipmentId就行; - 要是某个动作完全没关联任何器材,第一种写法里它的
已用器材ID列表会是NULL,FIND_IN_SET对NULL返回0,NOT 0为true,所以也会被正确筛选出来。
内容的提问来源于stack exchange,提问作者Ridge Robinson
相关产品推荐
相关产品推荐

