Skip to content

SELECT 与列:选择、别名与表达式 ​

SELECT 基础语法 ​

SELECT 是 SQL 中最常用的语句,用于从表中查询数据。

最简单的形式:

sql
SELECT * FROM users;
  • SELECT:关键字,表示查询操作
  • *:通配符,表示"所有列"
  • FROM users:从 users 表中查询

结果:

text
 id |  name   |        email        | age |       created_at
----+---------+---------------------+-----+------------------------
  1 | Alice   | alice@example.com   |  30 | 2026-09-20 10:30:00
  2 | Bob     | bob@example.com     |  25 | 2026-09-20 10:30:00
  3 | Charlie | charlie@example.com |  35 | 2026-09-20 10:30:00
  4 | Diana   | diana@example.com   |  28 | 2026-09-20 10:30:00
  5 | Eve     | eve@example.com     |     | 2026-09-20 10:30:00

选择特定列 ​

通常不需要所有列,只选择需要的列:

sql
SELECT name, email FROM users;

结果:

text
  name   |        email
---------+---------------------
 Alice   | alice@example.com
 Bob     | bob@example.com
 Charlie | charlie@example.com
 Diana   | diana@example.com
 Eve     | eve@example.com

为什么不总是用 SELECT *?

  1. 性能:减少网络传输和内存占用
  2. 明确性:代码更清晰,明确需要哪些列
  3. 维护性:表结构变化时不会意外获取新列

多列用逗号分隔,顺序可以与表定义不同:

sql
SELECT email, name, age FROM users;

列别名(AS) ​

使用 AS 给列起别名,让结果更易读:

sql
SELECT 
    name AS user_name,
    email AS contact_email,
    age AS user_age
FROM users;

结果:

text
 user_name |    contact_email    | user_age
-----------+---------------------+----------
 Alice     | alice@example.com   |       30
 Bob       | bob@example.com     |       25
 Charlie   | charlie@example.com |       35
 Diana     | diana@example.com   |       28
 Eve       | eve@example.com     |

AS 关键字可以省略(但不建议,降低可读性):

sql
SELECT name user_name FROM users;

别名中有空格时必须用引号:

sql
SELECT name AS "User Name" FROM users;

PostgreSQL 和标准 SQL 使用双引号,MySQL 可以用反引号:

sql
-- MySQL
SELECT name AS `User Name` FROM users;

表达式与计算 ​

SELECT 不仅能选择列,还能计算表达式:

算术运算 ​

sql
SELECT 
    name,
    age,
    age + 5 AS age_plus_5,
    age * 2 AS age_doubled
FROM users;

结果:

text
  name   | age | age_plus_5 | age_doubled
---------+-----+------------+-------------
 Alice   |  30 |         35 |          60
 Bob     |  25 |         30 |          50
 Charlie |  35 |         40 |          70
 Diana   |  28 |         33 |          56
 Eve     |     |            |

注意 Eve 的 age 是 NULL,任何对 NULL 的算术运算结果都是 NULL。

字符串拼接 ​

PostgreSQL:

sql
SELECT 
    name,
    email,
    name || ' <' || email || '>' AS full_contact
FROM users;

结果:

text
  name   |        email        |          full_contact
---------+---------------------+--------------------------------
 Alice   | alice@example.com   | Alice <alice@example.com>
 Bob     | bob@example.com     | Bob <bob@example.com>
 Charlie | charlie@example.com | Charlie <charlie@example.com>

MySQL 使用 CONCAT 函数:

sql
SELECT 
    name,
    email,
    CONCAT(name, ' <', email, '>') AS full_contact
FROM users;

常用函数 ​

字符串函数:

sql
SELECT 
    name,
    UPPER(name) AS uppercase,
    LOWER(name) AS lowercase,
    LENGTH(name) AS name_length
FROM users;

结果:

text
  name   | uppercase | lowercase | name_length
---------+-----------+-----------+-------------
 Alice   | ALICE     | alice     |           5
 Bob     | BOB       | bob       |           3
 Charlie | CHARLIE   | charlie   |           7

数学函数:

sql
SELECT 
    age,
    ROUND(age / 10.0, 1) AS age_decade,
    POWER(age, 2) AS age_squared
FROM users
WHERE age IS NOT NULL;

结果:

text
 age | age_decade | age_squared
-----+------------+-------------
  30 |        3.0 |         900
  25 |        2.5 |         625
  35 |        3.5 |        1225
  28 |        2.8 |         784

日期函数:

sql
SELECT 
    name,
    created_at,
    DATE(created_at) AS date_only,
    EXTRACT(YEAR FROM created_at) AS year,
    EXTRACT(MONTH FROM created_at) AS month
FROM users;

字面量与常量 ​

可以在 SELECT 中使用常量值:

sql
SELECT 
    name,
    'Active' AS status,
    100 AS points,
    TRUE AS is_verified
FROM users;

结果:

text
  name   | status | points | is_verified
---------+--------+--------+-------------
 Alice   | Active |    100 | t
 Bob     | Active |    100 | t
 Charlie | Active |    100 | t

这在生成报表或标记数据时很有用。

没有 FROM 的 SELECT ​

PostgreSQL 和标准 SQL 允许不带 FROM 的 SELECT,用于计算表达式:

sql
SELECT 1 + 1 AS result;

结果:

text
 result
--------
      2
sql
SELECT 
    NOW() AS current_time,
    CURRENT_DATE AS today,
    RANDOM() AS random_number;

MySQL 可以用 FROM DUAL(虚拟表):

sql
SELECT 1 + 1 AS result FROM DUAL;

DISTINCT 预览 ​

如果结果有重复行,可以用 DISTINCT 去重(后续章节详细讲解):

sql
-- 假设有重复的年龄
SELECT DISTINCT age FROM users WHERE age IS NOT NULL;

练习 ​

使用上一节创建的 users 表完成以下练习:

  1. 选择特定列:查询所有用户的姓名和邮箱。

  2. 使用别名:查询姓名(别名为 full_name)和年龄(别名为 years_old)。

  3. 字符串拼接:生成格式为 "姓名: 邮箱" 的字符串,别名为 contact_info。

  4. 年龄计算:计算每个用户 5 年后的年龄,别名为 age_in_5_years(注意 NULL 的处理)。

  5. 函数应用:查询姓名的大写形式和姓名长度。

  6. 常量列:查询所有用户,并添加一个常量列 country,值为 'China'。

  7. 当前时间:使用 SELECT 查询当前日期和时间(不需要 FROM 子句)。

完成练习后,打开本章答案页核对。

常见错误 ​

错误 1:列名拼写错误 ​

sql
SELECT nam FROM users;  -- 正确是 name

错误信息:

text
ERROR:  column "nam" does not exist

错误 2:忘记逗号 ​

sql
SELECT name email FROM users;  -- 缺少逗号

这会被解释为给 name 起别名 email,而不是选择两列。

错误 3:在别名中使用单引号 ​

sql
SELECT name AS 'user_name' FROM users;  -- 错误:应该用双引号

单引号用于字符串字面量,双引号用于标识符(列名、表名、别名)。

下一步 ​

学会了 SELECT 和列选择。下一节学习 WHERE 子句:如何过滤数据,只返回满足条件的行。

回到第一章概览 · 返回SQL 学习路线

用心记录每一步成长