MySQL ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ не дает правильных результатов

#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. Я знаю, что прошло много времени, но я просто хотел поблагодарить вас за этот ответ. который отлично работает