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;
类似的题目:
题目 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 左表.列 = 右表.列;