🙏 感谢您的支持! 我们在七月份已经筹集了 $65 — 这足够我们工作到下个月。请帮助我们保持进度,进一步支持这个项目。 支持这个项目 →
SQL 代码已复制到剪贴板

课程 2.1 · 阅读时间: ~6 分钟

从表中选择数据

SQL 中最基本的操作是从表中检索数据。SELECT 语句用于此目的。

SQL SELECT 和 DISTINCT 视觉指南

基本语法(选择所有列)

要从表中选择所有列,您可以使用 SELECT * 语法:

SELECT *
FROM table_name;
  • SELECT: 这个关键字用于从表中检索数据。
  • *(星号):表示应检索表中的所有列。星号 (*) 作为通配符,代表表中的所有列。
  • FROM table_name: 指定要从中检索数据的表。将 table_name 替换为您查询的实际表名。

示例(Sakila 数据库)

要从 Sakila 数据库中的 actor 表中选择所有列:

SELECT *
FROM actor;

此查询将返回 actor 表中的所有行和所有列(例如,actor_idfirst_namelast_namelast_update)。

避免使用 * 选择所有列

通常不建议使用 * 来选择所有列。虽然这看起来方便,但可能会导致几个问题:

  • 性能影响: 检索所有列可能会增加传输的数据量,特别是当表有许多列或大型数据集时。
  • 意外更改: 如果表模式发生变化(例如,添加新列),使用 * 的查询可能会返回意外的结果。
  • 可读性和维护性: 明确指定列使查询更易于理解和维护。

因此,最好明确列出您需要的列,而不是使用 *。这种方法确保了清晰性,减少了意外结果的风险,并提高了查询性能。

选择特定列

要检索特定列,请在 SELECT 语句中列出它们的名称,用逗号分隔:

SELECT column1, column2, column3
FROM table_name;
  • SELECT column1, column2, column3: 指定要检索的列。将 column1column2column3 替换为实际列名。
  • FROM table_name: 指示要从中检索数据的表。

示例(Sakila 数据库)

要仅从 actor 表中检索 first_namelast_name 列:

SELECT first_name, last_name
FROM actor;

此查询将返回所有行,但仅返回每个演员的 first_namelast_name 列。

使用 DISTINCT 选择唯一值

有时您不需要每一行,而只需要某一列(或一组列)中的唯一值。为此,请使用 DISTINCT 关键字。

基本语法

SELECT DISTINCT column_name
FROM table_name;

DISTINCT 从结果中删除重复项,仅保留唯一行。

示例(Sakila 数据库)

让我们获取唯一电影评分的列表:

SELECT DISTINCT rating
FROM film;

此查询仅返回每个 rating 值一次。

DISTINCT 与多个列

您还可以将 DISTINCT 应用于多个列。在这种情况下,唯一性由值的 组合 决定。

SELECT DISTINCT rating, rental_duration
FROM film;

在这里,基于 rating + rental_duration 的组合来删除重复项。

何时使用 DISTINCT

当您:

  • 构建参考列表(例如,唯一类别、状态或评分);
  • 检查数据质量(是否有意外的重复值?);
  • 为过滤器和用户界面控件准备数据。

如果您只需要检查一个值是否属于一个短列表,WHERE 中的 IN (...) 通常是更好的选择。使用 DISTINCT 专门用于从结果集中删除重复项。

SELECT 中的列顺序

SELECT 语句中列出列的顺序决定了它们在结果集中的顺序。然而,它不会改变表本身的列顺序。

示例(Sakila 数据库)

SELECT last_name, first_name
FROM actor;

在这种情况下,last_name 列将在输出中出现在 first_name 列之前,即使 first_name 可能在表结构中定义得更早。SELECT 语句中的顺序覆盖了默认的表列顺序。

常见问题

我可以在实际项目中使用 SELECT * 吗?

可以,但要有意识地使用它。它适合快速检查和调试,而生产查询通常在列出所需列时更安全。

SELECT 中的列顺序会改变表结构吗?

不会。它只会改变查询输出中列的顺序。数据库中的表定义保持不变。

为什么在 API 和报告中避免使用 SELECT *

因为模式更改可能会自动将列添加到结果中。这可能会破坏 API 合同、报告或期望固定字段集的客户端代码。

面试问题

SELECT * 的实际风险是什么?

主要风险是额外的数据传输、在模式更改时的稳定性较差,以及可读性降低。在生产代码中,面试官通常期望明确的列列表。

DISTINCT 何时会减慢查询?

在大型数据集上,因为数据库必须做额外的工作来删除重复项(通常是排序或哈希)。在需要唯一性时使用 DISTINCT,而不是默认使用。

SELECT DISTINCT a, b 返回什么?

它返回唯一的 (a, b) 对,而不是每列独立的唯一值。

如何选择 DISTINCTWHERE 过滤之间的区别?

使用 WHERE 按条件过滤行。使用 DISTINCT 从已经选择的行中删除重复项。


本课的关键要点:

  • SELECT * 从表中检索所有列。
  • SELECT column1, column2, ... 仅检索指定的列。
  • SELECT DISTINCT column_name 仅返回唯一值而不重复。
  • SELECT 语句中列的顺序决定了结果集中的顺序。

尝试解决以下任务,以巩固您在本课中学到的内容。

  1. 获取演员
  2. 检索演员姓名
  3. 语言列表
  4. 产品类别
  5. 唯一电影评分