【发布时间】:2010-10-15 22:53:39
【问题描述】:
我一直使用 INNER JOIN 和 LEFT OUTER JOIN。但是,我似乎从来不需要 RIGHT OUTER JOIN。
我见过很多使用右连接的讨厌的自动生成的 SQL,但对我来说,这些代码是不可能让我理解的。我总是需要使用内连接和左连接来重写它来制作它的头部或尾部。
真的有人使用右连接编写查询吗?
【问题讨论】:
标签: sql
我一直使用 INNER JOIN 和 LEFT OUTER JOIN。但是,我似乎从来不需要 RIGHT OUTER JOIN。
我见过很多使用右连接的讨厌的自动生成的 SQL,但对我来说,这些代码是不可能让我理解的。我总是需要使用内连接和左连接来重写它来制作它的头部或尾部。
真的有人使用右连接编写查询吗?
【问题讨论】:
标签: sql
举一个RIGHT JOIN可能有用的例子。
假设有三个表格,分别代表人物、宠物和宠物配饰。人们可以选择养宠物,这些宠物也可以选择拥有配饰
CREATE TABLE Persons
(
PersonName VARCHAR(10) PRIMARY KEY
);
INSERT INTO Persons
VALUES ('Alice'),
('Bob'),
('Charles');
CREATE TABLE Pets
(
PetName VARCHAR(10) PRIMARY KEY,
PersonName VARCHAR(10)
);
INSERT INTO Pets
VALUES ('Rover',
'Alice'),
('Lassie',
'Alice'),
('Fifi',
'Charles');
CREATE TABLE PetAccessories
(
AccessoryName VARCHAR(10) PRIMARY KEY,
PetName VARCHAR(10)
);
INSERT INTO PetAccessories
VALUES ('Ball', 'Rover'),
('Bone', 'Rover'),
('Mouse','Fifi');
如果要求获得列出所有人的结果,无论他们是否拥有宠物,以及有关他们拥有的任何宠物的信息。
这不起作用(不包括 Bob)
SELECT P.PersonName,
Pt.PetName,
Pa.AccessoryName
FROM Persons P
LEFT JOIN Pets Pt
ON P.PersonName = Pt.PersonName
INNER JOIN PetAccessories Pa
ON Pt.PetName = Pa.PetName;
这不起作用(包括 Lassie)
SELECT P.PersonName,
Pt.PetName,
Pa.AccessoryName
FROM Persons P
LEFT JOIN Pets Pt
ON P.PersonName = Pt.PersonName
LEFT JOIN PetAccessories Pa
ON Pt.PetName = Pa.PetName;
这确实有效(但语法不太常见,因为它需要两个连续的ON 子句才能实现所需的逻辑连接顺序)
SELECT P.PersonName,
Pt.PetName,
Pa.AccessoryName
FROM Persons P
LEFT JOIN Pets Pt
INNER JOIN PetAccessories Pa
ON Pt.PetName = Pa.PetName
ON P.PersonName = Pt.PersonName;
总而言之,RIGHT JOIN 可能最容易使用
SELECT P.PersonName,
Pt.PetName,
Pa.AccessoryName
FROM Pets Pt
JOIN PetAccessories Pa
ON Pt.PetName = Pa.PetName
RIGHT JOIN Persons P
ON P.PersonName = Pt.PersonName;
如果确定要避免这种情况,另一种选择是引入一个可以左连接的派生表
SELECT P.PersonName,
T.PetName,
T.AccessoryName
FROM Persons P
LEFT JOIN (SELECT Pt.PetName,
Pa.AccessoryName,
Pt.PersonName
FROM Pets Pt
JOIN PetAccessories Pa
ON Pt.PetName = Pa.PetName) T
ON T.PersonName = P.PersonName;
SQL 小提琴:MySQL、PostgreSQL、SQL Server
【讨论】:
WHERE PetAcessories.ID IS NOT NULL。执行计划将是相同的,并且查询的意图更具可读性。
我只使用 left,但我想说它们实际上是相同的,具体取决于您如何订购。我与一些只使用正确的人一起工作,因为他们从内到外构建查询并且喜欢将主要项目保留在底部,因此在他们看来,只使用正确是有意义的。
即
这里有重点
需要更多垃圾
More Junk right outer join Main Stuff
我更喜欢做主要的事情而不是垃圾......所以我只剩下外部工作了。
所以不管你的船是什么。
【讨论】:
很少,如前所述,您通常可以重新排序并使用左连接。此外,我自然倾向于对数据进行排序,这样左连接就可以获取我需要的数据。我认为完全外部连接和交叉连接也是如此,大多数人倾向于远离它们。
【讨论】:
您可以使用 LEFT 或 RIGHT 连接来完成同样的事情。一般来说,大多数人认为左连接可能是因为我们从左到右阅读。这真的归结为保持一致。您的团队应该专注于使用 LEFT 或 RIGHT 连接,而不是两者,因为它们本质上是完全相同的东西,但写法不同。
【讨论】:
我唯一一次使用右外连接是在我处理现有查询并需要更改它(通常从内部)时。我可以反转连接并使其左转并且可能没问题,但是我尝试减少修改代码时更改的内容的数量。
【讨论】:
这取决于您将每个表放在联接的哪一侧。
如果你想返回左表中的所有行,即使右表中没有匹配项......你使用左连接。
如果要返回右表中的所有行,即使左表中没有匹配项,也可以使用右连接。
有趣的是,我很少使用右连接。
【讨论】:
我们这里的标准做法是尽可能使用 LEFT JOIN 来编写所有内容。如果需要,我们偶尔会使用 FULL OUTER JOIN,但从不使用 RIGHT JOIN。
【讨论】:
您通常使用 RIGHT OUTER JOINS 在其他表中查找孤立项。
【讨论】:
不,我不这样做的原因很简单,我可以使用内连接或左连接来完成所有事情。
【讨论】: