#php #mysql #join
#php #mysql #Присоединиться
Вопрос:
Вероятно, это просто, но я не вижу проблемы…
У меня есть таблица MySQL, которая содержит индекс списков рассылки по названию. Эта таблица представляет собой СПИСКИ. Затем есть таблица пользователей и таблица подписок. Таблица подписок содержит простые записи, которые связывают пользователей с их списками рассылки.
Вызывающие беспокойство столбцы:
USERS u_id
LISTS l_id
SUBS s_id, u_id, l_id
Поэтому, когда пользователь 23 присоединяется к списку рассылки 7, запись, созданная в SUBS,:
s_id: 1 --
u_id: 23 --
l_id: 7
Вот в чем проблема:
Когда пользователь просматривает свои подписки, мне нужно отобразить таблицу, в которой отображаются все списки рассылки, в каждом из которых установлен флажок, если они уже подписаны на этот список.
Мой SQL, который неверен, но я не уверен, как, находится здесь:
SELECT l.l_id, l.l_name, l.l_desc,
CASE
WHEN s.u_id = '23' THEN 1 ELSE 0
END
FROM lists as l
LEFT OUTER JOIN
subs as s
ON s.l_id = l.l_id
GROUP BY l.l_id ASC
Это должно представлять 1, чтобы отметить соответствующие поля, и 0, чтобы оставить их пустыми.
Но поведение странное, потому что, когда я получаю * от subs, я вижу все ожидаемые целые. Однако приведенный выше SQL возвращает несколько пустых флажков, в которых существуют подписки. И что еще более странно, если все поля отмечены галочками, SQL не возвращает никаких галочек вообще.
Я слишком долго боролся с этим. Кто-нибудь может предложить решение?
Большое вам спасибо!
Ответ №1:
Проблема не в LEFT JOIN
этом, а в агрегации. Вам нужны функции агрегирования в SELECT
.
Однако я не думаю, что вам вообще нужна агрегация. Предполагая, что идентификатор пользователя появляется только один раз lists
для данного списка:
SELECT l.l_id, l.l_name, l.l_desc,
(s.l_id is not null) as flag
FROM lists l LEFT OUTER JOIN
subs s
ON s.l_id = l.l_id AND s.u_id = 23;
Вы можете выразить запрос по-своему (с агрегацией). Это будет выглядеть так:
SELECT l.l_id, l.l_name, l.l_desc,
MAX(s.u_id = 23) as flag
FROM lists l LEFT OUTER JOIN
subs s
ON s.l_id = l.l_id
GROUP BY l.l_id, l.l_name, l.l_desc;
Вы также можете использовать MAX(CASE s.u_id = 23 THEN 1 ELSE 0 END)
, но логическое сокращение MySQL более удобно и читаемо.
Комментарии:
1. Я знаю, что прошло много времени, но я просто хотел поблагодарить вас за этот ответ. который отлично работает