web-dev-qa-db-ja.com

MySQLはwhere句で結合します

結合したい2つのテーブルがあります。

カテゴリテーブルのすべてのカテゴリと、category_subscriptionsテーブルのユーザーがサブスクライブしているすべてのカテゴリが必要です。

基本的にこれはこれまでの私のクエリです:

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

すべてのカテゴリと、1つのクエリのみを使用して特定のユーザーがサブスクライブしているすべてのカテゴリを取得するにはどうすればよいですか?

category_idは、categoriesテーブルとuser_category_subscriptionsの両方のキーです。 user_category_subscriptionsテーブルにあるuser_id。

ありがとう

119
mmundiff

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_id1を使用して、categoriesのすべての行に結合します。これにより、categoriesのすべての行が得られますが、この特定のユーザーがサブスクライブしているcategoriesのみがuser_category_subscriptions列に情報を持ちます。もちろん、他のすべてのcategoriesには、user_category_subscriptions列のnullが入力されます。

逆に、where句は結合を行い、thenは行セットを削減します。したがって、これはすべての結合を実行し、user_id1と等しくないすべての行を削除します。 inner joinを取得するための非効率的な方法が残っています。

これがお役に立てば幸いです!

259
Eric

これを試して

  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