MySQL 什么时候使用左外连接?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5874733/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When to use a left outer join?
提问by John Conrad
I don't understand the concept of a left outer join, a right outer join, or indeed why we need to use a join at all! The question I am struggling with and the table I am working from is here: Link
我不明白左外连接、右外连接的概念,或者根本不明白为什么我们需要使用连接!我正在努力解决的问题以及我正在使用的表格在这里:链接
Question 3(b)
问题 3(b)
Construct a command in SQL to solve the following query, explaining why it had to employ the (outer) join method. [5 Marks] “Find the name of each staff member and his/her dependent spouse, if any”
在 SQL 中构造一个命令来解决以下查询,解释为什么它必须使用(外部)连接方法。[5 分] “请找出每位工作人员及其受抚养配偶的姓名(如有)”
Question 3(c) -
问题 3(c) -
Construct a command in SQL to solve the following query, using (i) the join method, and (ii) the subquery method. [10 Marks] “Find the identity name of each staff member who has worked more than 20 hours on the Computerization Project”
在 SQL 中构造一个命令来解决以下查询,使用 (i) 连接方法和 (ii) 子查询方法。【10分】“找出每个在计算机化项目中工作超过20小时的工作人员的身份名称”
Can anyone please explain this to me simply?
谁能简单地向我解释一下?
回答by Jordan Reiter
Joins are used to combine two related tables together.
联接用于将两个相关表组合在一起。
In your example, you can combine the Employee table and the Department table, like so:
在您的示例中,您可以组合 Employee 表和 Department 表,如下所示:
SELECT FNAME, LNAME, DNAME
FROM
EMPLOYEE INNER JOIN DEPARTMENT ON EMPLOYEE.DNO=DEPARTMENT.DNUMBER
This would result in a recordset like:
这将导致像这样的记录集:
FNAME LNAME DNAME
----- ----- -----
John Smith Research
John Doe Administration
I used an INNER JOIN
above. INNER JOIN
s combine two tables so that onlyrecords with matches in both tables are displayed, and they are joinedin this case, on the department number (field DNO in Employee, DNUMBER in Department table).
我用了INNER JOIN
上面的。INNER JOIN
小号组合两个表,以便只显示与两个表中记录的比赛,他们都加入了在这种情况下,部门编号(以员工现场DNO,DNUMBER在Department表)。
LEFT JOIN
s allow you to combine two tables when you have records in the first table but might nothave records in the second table. For example, let's say you want a list of all the employees, plus any dependents:
LEFT JOIN
当第一个表中有记录但第二个表中可能没有记录时,s 允许您合并两个表。例如,假设您想要一个包含所有员工以及任何家属的列表:
SELECT EMPLOYEE.FNAME as employee_first, EMPLOYEE.LNAME as employee_last, DEPENDENT.FNAME as dependent_last, DEPENDENT.LNAME as dependent_last
FROM
EMPLOYEE INNER JOIN DEPENDENT ON EMPLOYEE.SSN=DEPENDENT.ESSN
The problem here is that if an employee doesn'thave a dependent, then their record won't show up at all -- because there's no matching record in the DEPENDENT table.
这里的问题是,如果员工没有受抚养人,那么他们的记录根本不会显示——因为 DEPENDENT 表中没有匹配的记录。
So, you use a leftjoin which keeps all the data on the "left" (i.e. the first table) and pulls in any matching data on the "right" (the second table):
因此,您使用左连接将所有数据保留在“左侧”(即第一个表)并在“右侧”(第二个表)中提取任何匹配数据:
SELECT EMPLOYEE.FNAME as employee_first, EMPLOYEE.LNAME as employee_last, DEPENDENT.FNAME as dependent_first, DEPENDENT.LNAME as dependent_last
FROM
EMPLOYEE LEFT JOIN DEPENDENT ON EMPLOYEE.SSN=DEPENDENT.ESSN
Now we get allof the employee records. If there is no matching dependent(s) for a given employee, the dependent_first
and dependent_last
fields will be null.
现在我们得到了所有的员工记录。如果给定员工没有匹配的受抚养人,则dependent_first
和dependent_last
字段将为空。
回答by Johan
example(not using your example tables :-)
示例(不使用您的示例表:-)
I have a car rental company.
我有一家汽车租赁公司。
Table car
id: integer primary key autoincrement
licence_plate: varchar
purchase_date: date
Table customer
id: integer primary key autoincrement
name: varchar
Table rental
id: integer primary key autoincrement
car_id: integer
bike_id: integer
customer_id: integer
rental_date: date
Simple right? I have 10 records for cars because I have 10 cars.
I've been running this business for 10 years, so I've got 1000 customers.
And I rent the cars about 20x per year per cars = 10 years x 10 cars x 20 = 2000 rentals.
简单吧?我有 10 条汽车记录,因为我有 10 辆汽车。
我经营这家公司已经 10 年了,所以我有 1000 名客户。
我每年租车约 20 倍,每辆车 = 10 年 x 10 辆 x 20 = 2000 辆。
If I store everything in one big table I've got 10x1000x2000 = 20 million records.
If I store it in 3 tables I've got 10+1000+2000 = 3010 records.
That's 3 orders of magnitude, so that's why I use 3 tables.
如果我将所有内容都存储在一张大表中,我将得到 10x1000x2000 = 2000 万条记录。
如果我将它存储在 3 个表中,我有 10+1000+2000 = 3010 条记录。
这是 3 个数量级,这就是我使用 3 个表的原因。
But because I use 3 tables (to save space and time)I have to use joins in order to get the data out again
(at least if I want names and licence plates instead of numbers).
但是因为我使用了 3 个表(以节省空间和时间),所以我必须使用连接来再次获取数据
(至少如果我想要姓名和车牌而不是数字)。
Using inner joins
使用内连接
All rentals for customer 345?
客户 345 的所有租金?
SELECT * FROM customer
INNER JOIN rental on (rental.customer_id = customer.id)
INNER JOIN car on (car.id = rental.car_id)
WHERE customer.id = 345.
That's an INNER JOIN
, because we onlywant to know about cars linked to
rentals linked to
customers that actually happened.
这是一个INNER JOIN
,因为我们只是想了解汽车linked to
租赁linked to
实际发生的客户。
Notice that we also have a bike_id, linking to the bike table, which is pretty similar to the car table but different.
How would we get all bike + car rentals for customer 345.
We can tryand do this
请注意,我们还有一个自行车表,链接到自行车表,它与汽车表非常相似,但不同。我们如何获得客户 345 的所有自行车 + 汽车租赁。
我们可以尝试这样做
SELECT * FROM customer
INNER JOIN rental on (rental.customer_id = customer.id)
INNER JOIN car on (car.id = rental.car_id)
INNER JOIN bike on (bike.id = rental.bike_id)
WHERE customer.id = 345.
But that will give an empty set!!
This is because a rental can either be a bike_rental OR a car_rental, but not both at the same time.
And the non-working inner join
query will only give results for all rentals where we rent out both a bike and a car in the same transaction.
We are trying to get and boolean OR
relationship using a boolean AND
join.
但这将给出一个空集!!
这是因为租赁可以是自行车租赁或汽车租赁,但不能同时是两者。
并且非工作inner join
查询只会给出我们在同一笔交易中同时出租自行车和汽车的所有出租的结果。
我们正在尝试OR
使用布尔AND
连接来获取布尔关系。
Using outer joins
使用外连接
In order to solve this we need an outer join
.
为了解决这个问题,我们需要一个outer join
.
Let's solve it with left join
让我们解决它 left join
SELECT * FROM customer
INNER JOIN rental on (rental.customer_id = customer.id) <<-- link always
LEFT JOIN car on (car.id = rental.car_id) <<-- link half of the time
LEFT JOIN bike on (bike.id = rental.bike_id) <<-- link (other) 0.5 of the time.
WHERE customer.id = 345.
Look at it this way. An inner join
is an AND
and a left join
is a OR
as in the following pseudocode:
这样看。An inner join
is an AND
and a left join
is aOR
如以下伪代码所示:
if a=1 AND a=2 then {this is always false, no result}
if a=1 OR a=2 then {this might be true or not}
If you create the tables and run the query you can see the result.
如果您创建表并运行查询,您可以看到结果。
on terminology
关于术语
A left join
is the same as a left outer join
.
A join
with no extra prefixes is an inner join
There's also a full outer join
. In 25 years of programming I've never used that.
Aleft join
与 a 相同left outer join
。join
没有额外前缀的Ainner join
也是一个full outer join
. 在 25 年的编程生涯中,我从未使用过它。
Why Left join
为什么左加入
Well there's two tables involved. In the example we linked
customer to rental with an inner join
, in an inner join both tables mustlink so there is no difference between the left:customer
table and the right:rental
table.
嗯,涉及到两个表。在示例中,我们使用 将
客户链接到租赁inner join
,在内部联接中,两个表都必须链接,因此left:customer
表和right:rental
表之间没有区别。
The next link was a left join
between left:rental
and right:car
. On the left side all rows must link and the right side they don't have to. This is why it's a left join
下一个链接是left join
介于left:rental
和之间right:car
。在左侧,所有行都必须链接,而右侧则不必链接。这就是为什么它是一个left join
回答by Oded
You use outer joins when you need allof the results from one of the join tables, whether there is a matching row in the other table or not.
当您需要一个连接表中的所有结果时,无论另一个表中是否有匹配的行,您都可以使用外部连接。
回答by onedaywhen
I think Question 3(b) is confusing because its entire premise wrong: you don't have to use an outer join to "solve the query" e.g. consider this (following the style of syntax in the exam paper is probably wise):
我认为问题 3(b) 令人困惑,因为它的整个前提是错误的:您不必使用外连接来“解决查询”,例如考虑这一点(遵循试卷中的语法风格可能是明智的):
SELECT FNAME, LNAME, DEPENDENT_NAME
FROM EMPLOYEE, DEPENDENT
WHERE SSN = ESSN
AND RELATIONSHIP = 'SPOUSE'
UNION
SELECT FNAME, LNAME, NULL
FROM EMPLOYEE
EXCEPT
SELECT FNAME, LNAME, DEPENDENT_NAME
FROM EMPLOYEE, DEPENDENT
WHERE SSN = ESSN
AND RELATIONSHIP = 'SPOUSE'
回答by Sheng Chen
In general: JOIN joints two tables together. Use INNER JOIN when you wanna "look up", like look up detailed information of any specific column. Use OUTER JOIN when you wanna "demonstrate", like list all the info of the 2 tables.
一般而言: JOIN 将两个表连接在一起。当您想“查找”时使用 INNER JOIN,例如查找任何特定列的详细信息。当您想“演示”时使用 OUTER JOIN,例如列出 2 个表的所有信息。