MySQL dołącz z klauzulą ​​where

134

Mam dwa stoły, do których chcę dołączyć.

Chcę, aby wszystkie kategorie znajdowały się w tabeli kategorii, a także wszystkie kategorie zasubskrybowane przez użytkownika w tabeli category_subscriptions.

w zasadzie to jest moje zapytanie do tej pory:

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

Działa to dobrze, ale chcę dodać klauzulę where na końcu zapytania, która następnie zasadniczo czyni ją złączeniem wewnętrznym / 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

Jak uzyskać wszystkie kategorie, a także wszystkie kategorie zasubskrybowane przez określonego użytkownika za pomocą tylko jednego zapytania?

category_id jest kluczem zarówno w tabeli kategorii, jak i subskrypcji_kategorii_użytkowników. user_id rezydujący w tabeli user_category_subscriptions.

dzięki

mmundiff
źródło
Uważam, że nazywa się to „Prawym połączeniem”, jeśli się nie mylę?
Tyler Carter
@TylerCarter na pewno się mylisz :)
Scooter Daraf

Odpowiedzi:

296

Musisz to umieścić w joinklauzuli, a nie 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

Zobacz, z inner joinumieszczeniem klauzuli w joinlub wherejest równoważne. Jednak w przypadku pliku outer joinsą one bardzo różne.

W joinstanie określić zestaw wierszy, które będzie łączącą do stołu. Oznacza to, że user_id = 1najpierw oblicza i pobiera podzbiór user_category_subscriptionsz user_idlub, 1aby dołączyć do wszystkich wierszy w categories. To da ci wszystkie wiersze w categories, a tylko te, categoriesktóre subskrybował ten konkretny użytkownik, będą miały jakiekolwiek informacje w user_category_subscriptionskolumnach. Oczywiście wszystkie inne categorieszostaną wypełnione nullw user_category_subscriptionskolumnach.

I odwrotnie, whereklauzula wykonuje sprzężenie, a następnie zmniejsza zestaw wierszy. To wykonuje wszystkie łączenia, a następnie eliminuje wszystkie wiersze, w których user_idnie są równe 1. Pozostaje nieefektywny sposób na uzyskanie domeny inner join.

Mam nadzieję, że to pomoże!

Eric
źródło
2
Ładnie postawione pytanie i ładna odpowiedź! oszczędził mi czas. wielkie dzięki!
Gaurav Phapale
1
Tak bardzo cię kocham Eric, że uratowałeś mnie od płaczu: D
Raheel,
Z drugiej strony, jeśli chcę uzyskać czyste dane dla użytkowników, druga metoda (gdzie) jest bardziej odpowiednia. Czy to jest poprawne ?
vlr
1
Cześć, czy możemy wyrzucić user_category_subscriptions.user_id ma wartość null. Aby pobrać identyfikator detalu w tabeli A, który ma identyfikator zerowy w tabeli B
Veeresh123
@ Veeresh123, co to jest Ai Btabela? Czy możesz przeformułować swoje pytanie?
Istiaque Ahmed
11

Spróbuj tego

  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
jaffarali
źródło
Jeśli nadal otrzymuję ten sam błąd przy użyciu tego kodu, czego mam szukać dalej.
Jack Franzen