何时使用左外连接?

Joh*_*rad 29 mysql sql database-design join

我不理解左外连接,右外连接的概念,或者我们为什么需要使用连接!我正在努力解决的问题和我正在处理的表格在这里:链接

问题3(b)

在SQL中构造一个命令来解决以下查询,解释为什么必须使用(外部)连接方法.[5 Marks]"查找每位工作人员及其受抚养配偶的姓名,如果有的话"

问题3(c) -

使用(i)join方法和(ii)子查询方法在SQL中构造一个命令来解决以下查询.[10 Marks]"查找在计算机化项目上工作超过20小时的每位员工的身份名称"

有人可以简单地向我解释一下吗?

Jor*_*ter 82

连接用于将两个相关表组合在一起.

在您的示例中,您可以组合Employee表和Department表,如下所示:

SELECT FNAME, LNAME, DNAME
FROM
EMPLOYEE INNER JOIN DEPARTMENT ON EMPLOYEE.DNO=DEPARTMENT.DNUMBER
Run Code Online (Sandbox Code Playgroud)

这将导致记录集如下:

FNAME   LNAME   DNAME
-----   -----   -----
John    Smith   Research
John    Doe     Administration
Run Code Online (Sandbox Code Playgroud)

INNER JOIN上面用了一个.INNER JOIN小号组合两个表,以便显示与两个表中记录的比赛,他们都加入了在这种情况下,在部门号(场DNO的员工,DNUMBER在Department表).

LEFT JOIN■当第一个表中有记录但第二个表中可能没有记录时,允许您组合两个表.例如,假设您需要所有员工以及任何家属的列表:

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
Run Code Online (Sandbox Code Playgroud)

这里的问题是,如果员工没有受抚养人,那么他们的记录根本不会显示 - 因为在DEPENDENT表中没有匹配的记录.

因此,您使用连接将所有数据保留在"左"(即第一个表)上,并在"右"(第二个表)中提取任何匹配数据:

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
Run Code Online (Sandbox Code Playgroud)

现在我们获得所有员工记录.如果给定员工没有匹配的依赖项,则dependent_firstdependent_last字段将为null.


Joh*_*ica 25

示例(不使用您的示例表:-)

我有一家汽车租赁公司.

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
Run Code Online (Sandbox Code Playgroud)

简单吧?我有10条车的记录,因为我有10辆车.
我已经经营这家公司10年了,所以我有1000个客户.
而且每辆车每年租车约20倍= 10年x 10辆车x 20 = 2000辆.

如果我将所有内容存储在一个大表中,我有10x1000x2000 = 2000万条记录.
如果我将它存储在3个表中,我有10 + 1000 + 2000 = 3010条记录.
这是3个数量级,所以这就是我使用3个表的原因.

但是因为我使用3个表(为了节省空间和时间),我必须使用连接才能再次获取数据
(至少如果我需要名称和牌照而不是数字).

使用内连接

所有客户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.
Run Code Online (Sandbox Code Playgroud)

这是一个INNER JOIN,因为我们只是想了解汽车linked to出租linked to实际发生的客户.

请注意,我们还有一个bike_id,链接到自行车桌,非常类似于汽车桌,但不同.我们如何为客户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.
Run Code Online (Sandbox Code Playgroud)

但那将是一个空集!!
这是因为出租可以是自行车租赁或汽车租赁,但不能同时出租.
非工作inner join查询只会给出我们在同一笔交易中出租自行车和汽车的所有租赁结果.
我们试图OR使用布尔AND连接获得布尔关系.

使用外连接

为了解决这个问题,我们需要一个outer 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.
Run Code Online (Sandbox Code Playgroud)

以这种方式看待它.An inner join是a AND和a left joinOR如下伪代码:

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}
Run Code Online (Sandbox Code Playgroud)

如果您创建表并运行查询,则可以看到结果.

关于术语

A left join与a相同left outer join.A join没有额外的前缀是一个inner join 还有一个full outer join.在25年的编程中,我从未使用过它.

为什么左加入

那么涉及两个表.在示例中,我们将
客户与租赁联系起来inner join,在内部联接中,两个表都必须链接,因此left:customer表和right:rental表之间没有区别.

下一个链接是left join介于left:rental和之间right:car.在左侧,所有行必须链接,而右侧则不必.这就是它的原因left join