目录

SQL题型组合两个表

目录

SQL题型:组合两个表

例题:

表: Person

+-------------+---------+
| 列名         | 类型     |
+-------------+---------+
| PersonId    | int     |
| FirstName   | varchar |
| LastName    | varchar |
+-------------+---------+
personId 是该表的主键(具有唯一值的列)。
该表包含一些人的 ID 和他们的姓和名的信息。

表: Address

+-------------+---------+
| 列名         | 类型    |
+-------------+---------+
| AddressId   | int     |
| PersonId    | int     |
| City        | varchar |
| State       | varchar |
+-------------+---------+
addressId 是该表的主键(具有唯一值的列)。
该表的每一行都包含一个 ID = PersonId 的人的城市和州的信息。

要求: 编写解决方案,报告 Person

表中每个人的姓、名、城市和州。如果 personId

的地址不在 Address

表中,则报告为 null

。以 任意顺序

返回结果表。

解析:

Person 表(存储姓名)与 Address 表(存储地址)关联,展示每个人的完整信息。

LEFT JOIN :保证所有 Person 表中的记录都会被保留,无论 Address 表中是否有匹配的地址。

匹配条件 :通过 PersonId 关联两张表,确保同一个人的姓名和地址被正确对应。

所以结果应该是

  • 若某人有地址,显示其姓名、城市和州。
  • 若某人无地址,姓名正常显示,但城市和州为 NULL

解答代码:

select p.FirstName,p.LastName,a.City,a.State
from Person as p
left join Address as a on p.PersonId=a.PersonId;

https://i-blog.csdnimg.cn/direct/9b4275b186f54726bb516d546658b88c.png

类似的题目:

题目 1:学生与课程表

表结构:

Student

+———–+———+

| StudentId | int |

| Name | varchar |

+———–+———+

主键:StudentId

Course

+———–+———+

| CourseId | int |

| StudentId | int |

| Subject | varchar |

+———–+———+

主键:CourseId

问题:编写 SQL 查询所有学生的姓名及其选修的课程科目(包括未选课的学生)

SELECT s.Name, c.Subject
FROM Student AS s
LEFT JOIN Course AS c ON s.StudentId = c.StudentId;

题目 2:员工与部门表

表结构:

Employee

+———–+———+

| EmpId | int |

| Name | varchar |

+———–+———+

主键:EmpId

Department

+———–+———+

| DeptId | int |

| EmpId | int |

| DeptName | varchar |

+———–+———+

主键:DeptId

问题:编写 SQL 查询在 “技术部” 工作的员工姓名

SELECT e.Name
FROM Employee AS e
INNER JOIN Department AS d ON e.EmpId = d.EmpId
WHERE d.DeptName = '技术部';

题目 3:用户与订单表

表结构:

User

+———+———+

| UserId | int |

| Name | varchar |

+———+———+

主键:UserId

Order

+———+———+

| OrderId | int |

| UserId | int |

| Amount | decimal |

+———+———+

主键:OrderId

问题:编写 SQL 查询所有用户的姓名及其订单总金额(没有订单的显示 0)

select u.Name, COALESCE(SUM(o.Amount), 0) as TotalAmount
from User as u
left join Order as o on u.UserId = o.UserId
group by u.UserId, u.Name;

题目 4:书籍与作者表

表结构:

Book

+———+———+

| BookId | int |

| Title | varchar |

+———+———+

主键:BookId

Author

+———+———+

| AuthorId| int |

| BookId | int |

| Name | varchar |

+———+———+

主键:AuthorId

问题:编写 SQL 查询所有书籍的标题及其作者(包括未分配作者的书籍)

select b.Title,a.Name
from Book as b
left join Author as a on b.AuthorId=a.AuthorId

题目 5:客户与地址表

表结构:

Customer

+———–+———+

| CustId | int |

| Name | varchar |

+———–+———+

主键:CustId

Shipping

+———–+———+

| ShipId | int |

| CustId | int |

| Address | varchar |

+———–+———+

主键:ShipId

问题:编写 SQL 查询所有客户的姓名及其最近一次发货地址(假设最近一次发货地址由 ShipId 降序决定)

SELECT c.Name, s.Address
FROM Customer as c
LEFT JOIN (
    SELECT CustId, Address
    FROM Shipping
    WHERE ShipId = (SELECT MAX(ShipId) FROM Shipping as s2 WHERE s2.CustId = Shipping.CustId)
) as s ON c.CustId = s.CustId;

笔记:

1、 INNER JOIN (内连接)

INNER JOIN 只返回两个表中满足连接条件的记录组合。也就是说,只有当左表和右表中的记录在连接条件上匹配时,这些记录才会出现在结果集中。不满足连接条件的记录会被过滤掉。

SELECT 列名
FROM 1
INNER JOIN 2
ON 1. = 2.;

2、 LEFT JOIN (左连接)

LEFT JOIN (也称为 LEFT OUTER JOIN )会返回左表中的所有记录,无论右表中是否有匹配的记录。对于左表中的每一条记录,如果右表中有匹配的记录,则将匹配的记录组合在一起;如果右表中没有匹配的记录,则右表中的列将填充为 NULL

SELECT 列名
FROM 左表
LEFT JOIN 右表
ON 左表. = 右表.;

3、 RIGHT JOIN (右连接)

RIGHT JOIN (也称为 RIGHT OUTER JOIN )与 LEFT JOIN 相反,它会返回右表中的所有记录,无论左表中是否有匹配的记录。对于右表中的每一条记录,如果左表中有匹配的记录,则将匹配的记录组合在一起;如果左表中没有匹配的记录,则左表中的列将填充为 NULL

SELECT 列名
FROM 左表
RIGHT JOIN 右表
ON 左表. = 右表.;