MySQL объединяется с предложением where - PullRequest
118 голосов
/ 03 августа 2009

У меня есть две таблицы, к которым я хочу присоединиться.

Я хочу, чтобы все категории в таблице категорий, а также все категории, на которые подписался пользователь в таблице category_subscription.

По сути, это мой запрос:

SELECT *
FROM categories
LEFT JOIN user_category_subscriptions 
     ON user_category_subscriptions.category_id = categories.category_id

Это прекрасно работает, однако я хочу добавить предложение where в конце запроса, что затем делает его внутренним / равным соединением.

   SELECT *
    FROM categories
    LEFT JOIN user_category_subscriptions 
         ON user_category_subscriptions.category_id = categories.category_id 
   WHERE user_category_subscriptions.user_id = 1

Как получить все категории, а также все категории, на которые подписан конкретный пользователь, используя только один запрос?

category_id является ключом как в таблице категорий, так и в user_category_subscription. идентификатор_пользователя, находящийся в таблице user_category_subscription.

спасибо

Ответы [ 2 ]

257 голосов
/ 03 августа 2009

Вы должны поместить его в предложение join, а не where:

SELECT *
FROM categories
LEFT JOIN user_category_subscriptions ON 
    user_category_subscriptions.category_id = categories.category_id
    and user_category_subscriptions.user_id =1

См., С inner join добавление предложения в join или where эквивалентно. Однако с outer join они сильно отличаются.

В качестве условия join вы указываете набор строк, который вы будете присоединять к таблице. Это означает, что он сначала оценивает user_id = 1 и берет подмножество user_category_subscriptions с user_id из 1, чтобы объединить все строки в categories. Это даст вам все строки в categories, в то время как только столбцы categories, на которые подписался данный конкретный пользователь, будут иметь информацию в столбцах user_category_subscriptions. Конечно, все остальные categories будут заполнены null в столбцах user_category_subscriptions.

И наоборот, предложение where выполняет соединение, а , а затем уменьшает набор строк. Таким образом, это делает все объединения, а затем удаляет все строки, где user_id не равно 1. У вас остается неэффективный способ получить inner join.

Надеюсь, это поможет!

10 голосов
/ 09 июля 2012

Попробуйте это

  SELECT *
    FROM categories
    LEFT JOIN user_category_subscriptions 
         ON user_category_subscriptions.category_id = categories.category_id 
   WHERE user_category_subscriptions.user_id = 1 
          or user_category_subscriptions.user_id is null
...