MySQL приєднується до пункту де


130

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

Я хочу, щоб усі категорії в таблиці категорій, а також усі категорії, підписані користувачем у таблиці категорії_підписки.

по суті це мій запит досі:

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

Це добре працює, проте я хочу додати пункт де в кінці запиту, який по суті робить його внутрішнім / equi приєднанням.

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

Як я можу отримати всі категорії, а також усі категорії, підписані певним користувачем, використовуючи лише один запит?

категорія_ід є ключовою як у таблиці категорій, так і у підписках_користувача. user_id, що знаходиться в таблиці user_category_subscriptions.

Дякую


Я вважаю, що це називається "правильним приєднанням", якщо я не помиляюся?
Тайлер Картер

@TylerCarter ви напевно помилилися :)
Скутер Дараф

Відповіді:


287

Потрібно помістити це в 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.

Сподіваємось, це допомагає!


2
Приємно поставити питання, і приємно поставити відповідь! врятував мій час. дуже дякую!
Гаурав Фапале

1
Я так люблю тебе, Ерік, ти врятував мене від плачу: D
Рахіль

З іншого боку, якщо я хочу створити чисті дані для користувачів, другий (де) спосіб є більш підходящим. Це правильно ?
vlr

1
Привіт, ми можемо посміхнути user_category_subscriptions.user_id недійсним. Для того, щоб отримати детальний ідентифікатор у таблиці, яка має id null в B таблиці
Veeresh123

@ Veeresh123, що таке Aта Bстіл? Чи можете ви перефразувати своє запитання?
Істіак Ахмед

11

Спробуйте це

  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

Якщо я все-таки отримую ту саму помилку, використовуючи цей код, що я буду шукати далі.
Джек Францен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.