У меня есть таблицы соответствия и реакции следующим образом:
REACTION
+----------+----------+----------+----------+
| user_id | game_id | item_id | reaction |
+----------+----------+----------+----------+
| 1 | 1 | 1 | 1 |
| 1 | 1 | 2 | 1 |
| 2 | 1 | 1 | 1 |
| 2 | 1 | 2 | 0 |
+----------+----------+----------+----------+
MATCH:
+----------+----------+
| game_id | item_id |
+----------+----------+
| 1 | 1 |
| 1 | 2 |
+----------+----------+
Теперь я хочу (если возможно, без подзапросов) выбрать ВСЕ item_ids из таблицы MATCH И количество строк, где поле реакции в таблице Реакция равно 1 для пользователя с id = 2. Например, для определенных таблиц я хочу получить следующие результаты:
+----------+----------+
| item_id | count |
+----------+----------+
| 1 | 1 |
| 2 | 0 |
+----------+----------+
Я пробовал что-то вроде
SELECT match.item_id, COUNT(reaction.user_id) as c
FROM match
LEFT JOIN reaction ON reaction.item_id = match.item_id
WHERE reaction.reaction = 1 AND match.game_id = 2
GROUP BY match.item_id
HAVING c > 0
но это не сработало, как ожидалось. Я не могу получить счет для конкретного пользователя.
Я думаю, что вы близко. Я думаю, что вам просто нужно переместить условия на второй таблице в предложение ON
:
SELECT m.item_id, COUNT(r.user_id) as c
FROM match m LEFT JOIN
reaction r
ON r.item_id = m.item_id AND
r.reaction = 1 AND
r.user_id = 2
WHERE m.game_id = 2
GROUP BY m.item_id;
Я не уверен, для чего предназначен пункт HAVING
, потому что вы, кажется, хотите считать 0
.
Обратите внимание, что здесь также вводятся псевдонимы таблиц, поэтому запрос легче писать и читать.
У вас нет game_id = 2, поэтому это значение не должно возвращаться
и вы не должны использовать столбцы левой объединенной таблицы в условии условия, иначе эти wprk как внутреннее соединение... в этих случаях вы должны переместить соответствующее условие в предложении ON
SELECT match.item_id, COUNT(reaction.user_id) as c
FROM match
LEFT JOIN reaction ON reaction.item_id = match.item_id
AND reaction.reaction = 1
WHERE match.game_id = 2
GROUP BY match.item_id
HAVING c > 0
но попробуйте также
SELECT match.item_id, COUNT(reaction.user_id) as c
FROM match
LEFT JOIN reaction ON reaction.item_id = match.item_id
AND reaction.reaction = 1
GROUP BY match.item_id
SELECT match.item_id, COUNT(reaction.user_id) as c
FROM match JOIN reaction ON (reaction.item_id = match.item_id and reaction.reaction = 1 AND match.game_id = 2)
GROUP BY match.item_id
HAVING COUNT(reaction.user_id)
Я думаю, вам нужно отфильтровать 'перед' присоединением → так что используйте предложение 'on'. Фильтры, в where
применяются после выполнения объединения, в то время как фильтр, примененный on
предложению on
, применяются до выполнения объединения.