MySQL加入where子句


130

我有两个要加入的表。

我想要类别表中的所有类别以及用户在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

如何仅使用一个查询获取特定用户订阅的所有类别以及所有类别?

category_id是类别表和user_category_subscriptions中的键。驻留在user_category_subscriptions表中的user_id。

谢谢


我相信如果我没有记错的话,它被称为“ Right Join”?
泰勒·卡特

@TylerCarter您肯定弄错了:)
踏板车Daraf

Answers:


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_subscriptionsuser_id1加入到所有的行categories。这将为您提供中的所有行categories,而只有categories该特定用户已订阅的行中的列才包含任何信息user_category_subscriptions。当然,所有其他字段categoriesnull在各user_category_subscriptions列中填充。

相反,where子句进行联接,然后减少行集。因此,这将执行所有联接,然后消除所有user_id不等于的行1。您将获得效率低下的方法inner join

希望这会有所帮助!


2
很好地提出问题,很好地提出答案!节省了我的时间。非常感谢!
Gaurav Phapale 2013年

1
我非常爱你埃里克(Eric),你从哭泣中救了我:D
Raheel 2015年

另一方面,如果我想为用户生成干净的数据,则第二种方式更合适。这是正确的吗 ?
vlr

1
您好,我们可以查封user_category_subscriptions.user_id为null。为了在A表中检索详细ID,在B表中ID为null
Veeresh123 '16

@ Veeresh123,是什么AB表?你能改一下你的问题吗?
Istiaque Ahmed

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

如果使用此代码仍然遇到相同的错误,下一步该怎么做。
Jack Franzen 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.