Я не смог найти аналогичный вопрос с ответом, который я могу использовать, надеюсь, я не буду забывать о другом.
Я хочу создать запрос, который возвращает элементы, где значение НЕ В group_concat. Позвольте мне показать пример:
У меня есть таблица упражнений:
id | ExerciseName
---------------------
1 | Squat
2 | Deadlift
3 | Bench Press
4 | Deadlift Hex Bar
Затем у меня есть отдельная таблица, в которой показано, какое оборудование каждое из них использует:
id | ExerciseId | EquipmentId
---------------------------------
1 | 1 | 1
2 | 1 | 20
3 | 2 | 1
4 | 3 | 47
Затем у меня есть отдельная таблица, которая показывает, какое имя каждого оборудования:
id | name_en
-------------
1 | Barbell
2 | Squat Rack
3 | Dumbbell
Теперь у меня есть запрос, который я запускаю, который может выбирать упражнения, и я хочу запросить упражнения, ГДЕ оборудование доступно для пользователя. Итак, скажем, у Пользователя нет оборудования с Id = 1. Тогда я хотел бы вернуться только Упражнение 3. В настоящее время, по моему запросу, я получаю упражнение 1 и 3, и он делает это, потому что в упражнении 1 есть Идентификатор оборудования = 1, но у него также есть другой, который не равен Идентификатору оборудования = 1 (так как это Id = 20).
SELECT
we.id ExerciseId,
we.name_en ExerciseName
GROUP_CONCAT(DISTINCT weeq.name_en ORDER BY weeq.name_en SEPARATOR ', ') Equipment
FROM workouts_exercise we
JOIN workouts_exercise_equipment weeq ON weeq.exercise_id = we.id
JOIN workouts_equipment weq ON weq.id = weeq.equipment_id
WHERE weq.id NOT IN ("1")
GROUP BY we.id
Результаты этого, как упоминалось ранее, выглядят следующим образом:
ExerciseId | ExerciseName | Equipment
------------------------------------------
1 | Squat | 20
3 | Bench Press | 47
когда на самом деле все, что я хочу, это:
ExerciseId | ExerciseName | Equipment
------------------------------------------
3 | Bench Press | 47
Один из подходов - использовать анти-соединение для фильтрации упражнений, которые используют одно или несколько оборудования, которое вы хотите исключить:
SELECT
we1.ExerciseId,
ex.ExerciseName,
we1.EquipmentId AS Equipment
FROM workouts_equipment we1
LEFT JOIN workouts_equipment we2
ON we1.ExerciseId = we2.ExerciseId AND
we2.EquipmentId IN (1)
INNER JOIN workouts_exercise ex
ON we1.ExerciseId = ex.id
WHERE
we2.ExerciseId IS NULL;
we2.EquipmentId IN (1, 2, ...)
.
Вы хотите исключить упражнения, которые нуждаются в оборудовании 1. Вы можете использовать NOT IN
или NOT EXISTS
для этого:
select weeq.exerciseid, we.exercisename, weq.name_en as equipment
from workouts_exercise we
join workouts_exercise_equipment weeq on weeq.exerciseid = we.id
join workouts_equipment weq on weq.id = weeq.equipmentid
where we.id not in
(
select exerciseid from workouts_exercise_equipment where equipmentid = 1
)