Article / 文章

LeetCode 第175题:组合两个表

表: Person +-------------+---------+ | 列名 | 类型 | +-------------+---------+ | PersonId | int | | FirstName | varchar | | LastName | varchar | +-------------+---------+ PersonId 是该表的主

题目描述

表: Person

+-------------+---------+
| 列名         | 类型     |
+-------------+---------+
| PersonId    | int     |
| FirstName   | varchar |
| LastName    | varchar |
+-------------+---------+
PersonId 是该表的主键

表: Address

+-------------+---------+
| 列名         | 类型    |
+-------------+---------+
| AddressId   | int     |
| PersonId    | int     |
| City        | varchar |
| State       | varchar |
+-------------+---------+
AddressId 是该表的主键

编写一个SQL查询来报告 Person 表中每个人的姓、名、城市和州。如果 PersonId 的地址不在 Address 表中,则报告为空 null 。

难度

简单

题目链接

点击在LeetCode中查看题目

示例

示例1:

Person表:
+----------+----------+-----------+
| PersonId | LastName | FirstName |
+----------+----------+-----------+
| 1        | Wang     | Allen     |
| 2        | Alice    | Bob       |
+----------+----------+-----------+

Address表:
+-----------+----------+---------------+------------+
| AddressId | PersonId | City          | State      |
+-----------+----------+---------------+------------+
| 1         | 2        | New York City | New York   |
| 2         | 3        | Leetcode      | California |
+-----------+----------+---------------+------------+

输出: 
+-----------+----------+---------------+----------+
| FirstName | LastName | City          | State    |
+-----------+----------+---------------+----------+
| Allen     | Wang     | Null          | Null     |
| Bob       | Alice    | New York City | New York |
+-----------+----------+---------------+----------+

解释: 
地址表中没有 PersonId = 1 的地址,所以它们的城市和州返回 null。
AddressId = 1 包含了 PersonId = 2 的地址信息。

提示

  • 语句的执行环境为SQL Server

解题思路

方法:LEFT JOIN

这道题要求我们查询 Person 表中每个人的姓、名、城市和州,如果某个人在 Address 表中没有对应的地址,则城市和州应该报告为 null。

解题的关键在于使用 LEFT JOIN(左连接)操作,它能确保 Person 表中的每一条记录都会出现在结果集中,即使这个人在 Address 表中没有对应的地址信息。

步骤:

  1. 以 Person 表作为左表,Address 表作为右表
  2. 使用 PersonId 作为连接条件进行 LEFT JOIN
  3. 选择需要的列:FirstName, LastName, City 和 State

SQL中的主要连接类型及其区别:

  • INNER JOIN(内连接):仅返回两表中匹配的行
  • LEFT JOIN(左连接):返回左表中的所有行,右表没有匹配的行则用 NULL 值填充
  • RIGHT JOIN(右连接):返回右表中的所有行,左表没有匹配的行则用 NULL 值填充
  • FULL JOIN(全连接):返回两表中的所有行,任何不匹配的行则用 NULL 值填充

时间复杂度:O(n+m),其中 n 和 m 分别是 Person 表和 Address 表的行数 空间复杂度:O(n),需要存储结果集

代码实现

SQL 实现

SELECT P.FirstName, P.LastName, A.City, A.State
FROM Person P
LEFT JOIN Address A
ON P.PersonId = A.PersonId;

性能分析

SQL 查询的性能分析:

特点 说明
执行用时 392 ms
内存消耗 0B
特点 简单直观的 LEFT JOIN 操作

补充说明

代码亮点

  1. 使用 LEFT JOIN 确保 Person 表中的所有人都会被查询出来
  2. 清晰的列名前缀(P. 和 A.)提高了查询的可读性
  3. 简洁明了的实现,没有复杂的条件判断

常见错误

  1. 使用 INNER JOIN 而不是 LEFT JOIN,导致没有地址信息的人被过滤掉
  2. 忘记指定表别名,在复杂查询中可能导致列引用不明确
  3. JOIN 条件使用错误的列,导致连接结果不正确

相关题目