Skip to content

SELECT 查询

SELECT 是 SQL 中最常用、最重要的语句,用于从数据库中检索数据。本章将详细介绍 SELECT 语句的各种用法,让你能够灵活地从数据库中查询所需的数据。

基本语法

SELECT 语句结构

sql
SELECT column1, column2, ...
FROM table_name;

查询所有列

使用 * 通配符查询表中的所有列:

sql
SELECT * FROM users;

注意:在实际应用中,应该明确指定需要的列,而不是使用 *,以提高性能。

查询指定列

只查询需要的列:

sql
SELECT name, age, city FROM users;

查询并排序

sql
SELECT name, age 
FROM users 
ORDER BY age;

查询单个表

准备数据

假设我们有以下 users 表:

idnameagecityemail
1张三25北京zhang@example.com
2李四30上海li@example.com
3王五28广州wang@example.com
4赵六35北京zhao@example.com
5钱七22深圳qian@example.com

查询所有数据

sql
SELECT * FROM users;

结果:

idnameagecityemail
1张三25北京zhang@example.com
2李四30上海li@example.com
3王五28广州wang@example.com
4赵六35北京zhao@example.com
5钱七22深圳qian@example.com

查询特定列

sql
SELECT name, age FROM users;

结果:

nameage
张三25
李四30
王五28
赵六35
钱七22

使用别名(AS)

为列指定别名,使结果更易读:

sql
SELECT 
    name AS 姓名,
    age AS 年龄,
    city AS 城市
FROM users;

结果:

姓名年龄城市
张三25北京
李四30上海
王五28广州
赵六35北京
钱七22深圳

注意AS 关键字是可选的,可以省略:

sql
SELECT name 姓名, age 年龄, city 城市
FROM users;

去重查询

DISTINCT 关键字

使用 DISTINCT 消除重复的行:

sql
SELECT DISTINCT city FROM users;

结果:

city
北京
上海
广州
深圳

多列去重

对多列的组合进行去重:

sql
SELECT DISTINCT city, age FROM users;

计算列

基本计算

在查询中可以对列进行计算:

sql
SELECT 
    name,
    age,
    age * 2 AS 双倍年龄
FROM users;

结果:

nameage双倍年龄
张三2550
李四3060
王五2856
赵六3570
钱七2244

字符串拼接

sql
-- MySQL
SELECT 
    name,
    CONCAT(name, ' (', city, ')') AS 用户信息
FROM users;

-- PostgreSQL
SELECT 
    name,
    name || ' (' || city || ')' AS 用户信息
FROM users;

条件表达式

使用 CASE WHEN 进行条件判断:

sql
SELECT 
    name,
    age,
    CASE 
        WHEN age < 25 THEN '年轻'
        WHEN age < 35 THEN '中年'
        ELSE '年长'
    END AS 年龄分组
FROM users;

结果:

nameage年龄分组
张三25中年
李四30中年
王五28中年
赵六35年长
钱七22年轻

限制结果数量

LIMIT 子句

限制返回的行数:

sql
-- 只返回前 3 条记录
SELECT * FROM users LIMIT 3;

结果:

idnameagecityemail
1张三25北京zhang@example.com
2李四30上海li@example.com
3王五28广州wang@example.com

LIMIT 和 OFFSET 结合

分页查询:

sql
-- 跳过前 2 条,返回接下来的 3 条
SELECT * FROM users LIMIT 3 OFFSET 2;

MySQL 的分页语法

sql
-- 返回第 1 页(每页 2 条)
SELECT * FROM users LIMIT 0, 2;

-- 返回第 2 页(每页 2 条)
SELECT * FROM users LIMIT 2, 2;

SQL Server 的分页语法

sql
-- 使用 OFFSET-FETCH
SELECT * FROM users
ORDER BY id
OFFSET 0 ROWS
FETCH NEXT 2 ROWS ONLY;

排序结果

ORDER BY 子句

使用 ORDER BY 对结果进行排序:

sql
-- 按年龄升序排序
SELECT name, age FROM users ORDER BY age;

结果:

nameage
钱七22
张三25
王五28
李四30
赵六35

降序排序

使用 DESC 关键字:

sql
-- 按年龄降序排序
SELECT name, age FROM users ORDER BY age DESC;

结果:

nameage
赵六35
李四30
王五28
张三25
钱七22

多列排序

sql
-- 先按城市排序,再按年龄排序
SELECT name, city, age 
FROM users 
ORDER BY city, age;

使用列别名排序

sql
SELECT 
    name,
    age * 2 AS 双倍年龄
FROM users
ORDER BY 双倍年龄 DESC;

空值处理

COALESCE 函数

返回第一个非 NULL 的值:

sql
-- 假设 email 列可能有 NULL 值
SELECT 
    name,
    COALESCE(email, '未填写邮箱') AS 邮箱
FROM users;

NULLIF 函数

如果两个参数相等,返回 NULL:

sql
SELECT 
    name,
    age,
    NULLIF(age, 0) AS 检查年龄
FROM users;

字符串函数

CONCAT 函数

sql
-- MySQL
SELECT CONCAT(name, ' - ', city) FROM users;

UPPER 和 LOWER

sql
SELECT UPPER(name) FROM users;  -- 转大写
SELECT LOWER(name) FROM users;  -- 转小写

SUBSTRING

sql
-- 截取字符串
SELECT SUBSTRING(name, 1, 2) FROM users;  -- 取前2个字符

LENGTH

sql
-- 获取字符串长度
SELECT LENGTH(name) FROM users;

日期函数

CURRENT_DATE / CURRENT_TIME

sql
SELECT CURRENT_DATE;  -- 当前日期
SELECT CURRENT_TIME;  -- 当前时间

DATE_FORMAT(MySQL)

sql
SELECT 
    name,
    DATE_FORMAT(created_at, '%Y-%m-%d') AS 注册日期
FROM users;

DATE_PART(PostgreSQL)

sql
SELECT 
    name,
    DATE_PART('year', created_at) AS 年份
FROM users;

实战示例

示例 1:查询活跃用户

sql
SELECT 
    username,
    email,
    last_login
FROM users
WHERE last_login >= DATE_SUB(NOW(), INTERVAL 30 DAY)
ORDER BY last_login DESC;

示例 2:统计各城市用户数

sql
SELECT 
    city AS 城市,
    COUNT(*) AS 用户数
FROM users
GROUP BY city
ORDER BY 用户数 DESC;

示例 3:查询高价值客户

sql
SELECT 
    u.username,
    u.email,
    SUM(o.total_amount) AS 总消费,
    COUNT(o.id) AS 订单数
FROM users u
JOIN orders o ON u.id = o.user_id
GROUP BY u.id
HAVING 总消费 > 1000
ORDER BY 总消费 DESC;

性能优化建议

1. 避免使用 SELECT *

sql
-- 不推荐:查询所有列
SELECT * FROM users;

-- 推荐:只查询需要的列
SELECT id, name, email FROM users;

2. 使用 WHERE 而不是 HAVING

sql
-- 不推荐:在 HAVING 中过滤
SELECT city, COUNT(*)
FROM users
GROUP BY city
HAVING city = '北京';

-- 推荐:在 WHERE 中过滤
SELECT city, COUNT(*)
FROM users
WHERE city = '北京'
GROUP BY city;

3. 合理使用 LIMIT

sql
-- 分页查询
SELECT * FROM users
ORDER BY id
LIMIT 10 OFFSET 20;

4. 为常用查询创建索引

sql
-- 为经常查询的列创建索引
CREATE INDEX idx_user_name ON users(name);

常见错误

错误 1:列名拼写错误

sql
-- 错误:列名不存在
SELECT nam FROM users;

-- 正确
SELECT name FROM users;

错误 2:忘记 FROM 子句

sql
-- 错误:缺少 FROM
SELECT name, age;

-- 正确
SELECT name, age FROM users;

错误 3:列别名使用不当

sql
-- 错误:在某些数据库中,别名不能在 WHERE 中使用
SELECT name, age * 2 AS 双倍年龄
FROM users
WHERE 双倍年龄 > 50;

-- 正确:在 WHERE 中使用原始表达式
SELECT name, age * 2 AS 双倍年龄
FROM users
WHERE age * 2 > 50;

小结

本章介绍了 SELECT 查询的基本用法:

  • 基本语法:SELECT column FROM table
  • 查询所有列:使用 * 通配符
  • 查询指定列:明确列出需要的列
  • 列别名:使用 AS 为列指定别名
  • 去重查询:使用 DISTINCT
  • 计算列:在查询中进行计算
  • 限制结果:使用 LIMIT 和 OFFSET
  • 排序结果:使用 ORDER BY
  • 字符串函数:CONCAT、UPPER、LOWER 等
  • 日期函数:CURRENT_DATE、DATE_FORMAT 等

SELECT 是 SQL 中最重要的语句,掌握它的各种用法是学习 SQL 的基础。在下一章中,我们将学习如何使用 WHERE 子句来过滤数据。

下一步: 学习 WHERE 条件,学习如何过滤查询结果。