我有两张表,如下:
人:
First_Name Last_Name
Bill Smith
David Williams
Fred Jones
Freda Jones
Jane Smith
John Smith
Peter Williams
Sally Williams
宠物:
Species Title Owner
Dog Fido Jones
Cat Tibs Jones
Dog Jock Williams
我知道这是一个奇怪的数据库设计,但请不要告诉我重新设计数据库。这是一个代表真实问题的例子,它更复杂,无法重新设计。
我正在尝试制定一个查询,它将为每个人返回一行,以及一个包含其Cat标题的列,如果他们没有猫,则为null(我使用Title
因为{{1}是一个保留字和Access抱怨)。
我最接近的是:
Name
然而,这并未列出威廉姆斯家族的任何行,因为他们拥有一只狗。
我已经将其标记为MS Access,因为我实际上使用的是Access 97(请不要问!),但是,除了Access相当有限的Join设施之外,它应该是一般的SQL问题。
答案 0 :(得分:5)
编辑:Access中的左连接语法会导致故障,这意味着对于访问,我们需要涉及子查询。这看起来像(未经测试的);
SELECT People.*, Pets.Title
FROM People LEFT JOIN
[SELECT Pets.* FROM Pets WHERE Pets.Species = 'Cat']. AS Pets
ON People.Last_Name = Pets.Owner
- 原始答案 -
你似乎想要的是一个常规的左连接,另外一个条件是宠物需要成为一只猫;
SELECT People.*, Pets.Title
FROM People LEFT JOIN Pets
ON People.Last_Name = Pets.Owner AND Pets.Species = 'Cat'
不将cat条件放在WHERE
子句中的原因是where子句消除了所有非匹配,而将它放在ON
子句中会产生结果如果无法找到匹配项,则为NULL(正如您描述的所需结果)
答案 1 :(得分:1)
这并未列出威廉姆斯家族的任何行,因为他们拥有一只狗
那是因为WHERE
条款:
WHERE Pets.Species IS NULL OR Pets.Species = "Cat"
如果Pets.Species
为"Dog"
,那么这将评估为false,因此不会显示这些记录。首先完全删除该条款:
SELECT People.*, Pets.Title
FROM People
LEFT JOIN Pets ON People.Last_Name = Pets.Owner
现在您正在获取所需的记录,但不是您想要的数据。 Title
列显示任意值,您只希望它显示"Cat"
或NULL
。您可以调整JOIN
来实现:
SELECT People.*, Pets.Title
FROM People
LEFT JOIN Pets ON People.Last_Name = Pets.Owner
AND Pets.Species = 'Cat'
这将过滤已加入的表,但不会过滤整个结果集。
答案 2 :(得分:0)
试试这个
SELECT People.*, case when Pets.Species = 'Cat' then Pets.Title else null end as Title
FROM People LEFT JOIN Pets ON People.Last_Name = Pets.Owner
答案 3 :(得分:0)
对于后人 - 我终于得到了它:
SELECT People.*, Pets.Title FROM
People LEFT JOIN (SELECT * FROM Pets WHERE Species='Cat') AS PeopleWithCats
ON People.Last_Name=PeopleWithCats.Owner