⏳ 十月只剩最后几天!SQLtest.online 依靠捐款免费运营,我们仍需达成本月目标,才能让网站在十一月继续运行。每一份捐款都很重要。 立即支持 →
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_id、first_name、last_name、last_update)。

避免用 * 查询所有列

一般不建议用 * 查询所有列。它看起来很方便,但可能带来几个问题:

  • 影响性能: 取出所有列会增加传输的数据量,尤其是在表的列很多或数据量很大时。
  • 意外变化: 如果表结构发生变化(例如新增了列),使用 * 的查询可能返回意料之外的结果。
  • 可读性和维护: 明确写出列名会让查询更容易理解和维护。

最佳做法是明确列出你需要的列,而不是使用 *。这样查询更清晰,能降低出现意外结果的风险,还能提升查询性能。

查询指定的列

要取出指定的列,在 SELECT 语句中列出它们的名称,用逗号分隔:

SELECT column1, column2, column3
FROM table_name;
  • SELECT column1, column2, column3:指定要取出的列。请把 column1、column2 和 column3 换成实际的列名。
  • FROM table_name:指定从哪张表取数据。

示例(Sakila 数据库)

只取出 actor 表中的 first_name 和 last_name 列:

SELECT first_name, last_name
FROM actor;

这条查询会返回所有行,但每位演员只显示 first_name 和 last_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

DISTINCT 在以下场景中很有用:

  • 构建参考列表(例如唯一的类别、状态或分级);
  • 检查数据质量(是否存在意外的重复值?);
  • 为筛选器和界面控件准备数据。

如果只需要检查某个值是否属于一个简短的列表,在 WHERE 中使用 IN (...) 通常更合适。DISTINCT 专门用于去除结果集中的重复项。

SELECT 中的列顺序

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

示例(Sakila 数据库)

SELECT last_name, first_name
FROM actor;

在这个例子中,即使表结构中 first_name 定义在前,输出时 last_name 列也会出现在 first_name 列之前。SELECT 语句中的顺序优先于表的默认列顺序。

常见问题

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

可以,但要有意识地使用。它适合快速检查和调试,而生产环境中的查询通常只列出需要的列会更安全。

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

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

为什么在 API 和报表中要避免 SELECT *?

因为表结构变化可能会自动给结果增加列。这可能破坏 API 约定、报表,或者依赖固定字段集合的客户端代码。

面试问题

SELECT * 的实际风险是什么?

主要风险是多传输数据、表结构变化时稳定性较差,以及可读性降低。对于生产代码,面试官通常希望看到明确的列清单。

DISTINCT 什么时候会让查询变慢?

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

SELECT DISTINCT a, b 返回什么?

它返回唯一的 (a, b) 组合,而不是各列各自的唯一值。

如何在 DISTINCT 和 WHERE 过滤之间选择?

用 WHERE 按条件过滤行,用 DISTINCT 去除已选出的行中的重复项。


本课要点:

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

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

  1. 获取演员
  2. 检索演员姓名
  3. 语言列表
  4. 检索所有部门
  5. 员工姓名