左外连接有多个匹配,如何返回特定的一个?

时间:2016-09-20 16:52:14

标签: mysql sql left-join

我有一个问题,我认为可以通过正确使用左外连接来解决,但我无法构造合适的查询。 OTOH,可能还有一些其他更聪明的SQL解决方案。此外,这可以通过一些编程轻松解决,但我想避免这种情况,并尽可能找到“干净”的解决方案。

背景:假设我正在创建一个列出一些汽车品牌的网站,用户可以选择他拥有/拥有的那些(我不是真的这样做,但这个例子说明了这一点)。另外,对于所选择的那些,他可以选择性地输入关于它们的一些附加信息,例如,年和一些自由文本,如特定的模型,评论或其他。此外,输入的信息存储在关系数据库(我的情况下是MySQL)中,用户可以在以后检索并更改其答案。

假设有两个数据库表:

BRAND
------------
ID INT
NAME VARCHAR(50)

OWNED
------------
ID INT
BRAND_ID INT
OWNER_ID INT
YEAR INT
COMMENT VARCHAR(100)

(此处BRAND_ID + OWNER_ID是一个唯一索引,因此每个BRAND / OWNER组合只能有一行,因此只有一年和一个评论)

这些表格中的数据可能如下所示:

BRAND
--------------
ID | NAME
--------------
1  | Cadillac
2  | Chevrolet
3  | Dodge
4  | Ford

OWNED
-----------------------------------------
ID | BRAND_ID | OWNER_ID | YEAR | COMMENT
-----------------------------------------
1  | 1        | 1        | null | 70's Fleetwood
2  | 2        | 1        | 2000 | Crappy car
3  | 2        | 2        | null | I really liked it
4  | 4        | 2        | 1999 | null

现在,为了方便创建网页,我想做的是用一个SELECT显示表BRAND中的所有品牌,并且每个BRAND知道当前用户是否拥有它,如果他有,也列出他的年份和评论(如果有的话)。换句话说,这样的事情(假设当前用户是2):

NAME      | OWNER_ID | YEAR | COMMENT
-------------------------------------
Cadillac  | null     | null | null
Chevrolet | 2        | null | I really liked it
Dodge     | null     | null | null
Ford      | 2        | 1999 | null

我尝试过这样的事情:

select NAME, OWNER_ID, YEAR, COMMENT from BRAND left join OWNED on 
BRAND.ID = OWNED.BRAND_ID where OWNER_ID = 2 or OWNER_ID = null

但是失败了,因为1拥有凯迪拉克,因此结果留下了凯迪拉克。 OTOH如果我省略了where子句,我将为雪佛兰获得两行,这也是不可取的。

所以,如果有一个带有SQL的干净解决方案(有或没有左外连接),我想知道如何做到这一点?

2 个答案:

答案 0 :(得分:1)

我猜你想要这个:

select NAME, OWNER_ID, YEAR, COMMENT
from BRAND left join
     OWNED o
     on BRAND.ID = OWNED.BRAND_ID and OWNER_ID = 2 ;

答案 1 :(得分:0)

似乎您可能真正想要的是所有者列表,然后是他们拥有的内容和详细信息。你可以通过调整这个底部的所有者ID来实现:

SELECT owned.owner_id, brand.id, brand.name, owned.year, owned.comment 
FROM owned
INNER JOIN brand
ON owned.brand_id = brand.id
WHERE owned.owner_id = 2

在这里测试:http://sqlfiddle.com/#!9/5b52ba