web-dev-qa-db-fra.com

MySQL rejoindre avec la clause where

J'ai deux tables que je veux rejoindre.

Je veux toutes les catégories de la table categories ainsi que toutes les catégories auxquelles un utilisateur a souscrit dans la table category_subscriptions.

essentiellement, voici ma question:

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

Cela fonctionne bien, mais je souhaite ajouter une clause where à la fin de la requête, ce qui en fait essentiellement une jointure inner/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

Comment obtenir toutes les catégories ainsi que toutes les catégories auxquelles un utilisateur donné a souscrit en utilisant une seule requête?

category_id étant une clé dans les tables de catégories et user_category_subscriptions. user_id résidant dans la table user_category_subscriptions.

merci

119
mmundiff

Vous devez le mettre dans la clause join, pas dans le 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

Voir, avec un inner join, mettre une clause dans join ou where est équivalent. Cependant, avec un outer join, ils sont très différents.

En tant que condition join, vous spécifiez le jeu de lignes que vous allez joindre à la table. Cela signifie qu'il évalue user_id = 1 _ d'abord, et prend le sous-ensemble de user_category_subscriptions avec un user_id de 1 pour rejoindre toutes les lignes de categories. Cela vous donnera toutes les lignes dans categories, alors que seul le categories auquel cet utilisateur particulier est abonné aura une information dans le user_category_subscriptions Colonnes. Bien entendu, tous les autres categories seront renseignés avec null dans le user_category_subscriptions Colonnes.

Inversement, une clause where effectue la jointure et then réduit l'ensemble de lignes. Donc, cela fait toutes les jointures et ensuite élimine toutes les lignes où user_id n'est pas égal à 1. Vous vous retrouvez avec un moyen inefficace d'obtenir un inner join.

Espérons que cela aide!

259
Eric

Essaye ça

  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
10
jaffarali