检索数据
SELECT 语句用于从一个表或多个表中检索出想要的数据行。它是 SQL 中最常用的语句。本文聚焦 SELECT 基础语法速查(单表投影、去重、排序、分页与执行顺序),多条件过滤见《05-数据过滤》,综合组合实战见《06-综合查询实战》。
SELECT 查询基础
基本语法
sql
SELECT 列名 FROM 表名;查询示例
使用王者荣耀英雄数据表(共 69 个英雄,23 个属性值):
查询单列:
sql
SELECT name FROM heros;查询多列:
sql
SELECT name, hp_max, mp_max, attack_max, defense_max FROM heros;查询所有列:
sql
SELECT * FROM heros;最佳实践:在生产环境中尽量避免使用
SELECT *,明确指定需要的列可以提高查询效率,减少网络传输。
起别名
为列名起别名,使结果更易读:
sql
SELECT name AS n, hp_max AS hm, mp_max AS mm FROM heros;
-- 省略 AS 关键字
SELECT name n, hp_max hm FROM heros;查询常数
在查询结果中添加固定的常数列:
sql
-- 添加字符串常数
SELECT '王者荣耀' AS platform, name FROM heros;
-- 添加数字常数
SELECT 123 AS platform, name FROM heros;使用场景:
- 整合不同数据源时作为标记
- 导出数据时添加标识列
去除重复行
使用 DISTINCT 关键字去除重复值:
sql
-- 查询所有攻击范围类型
SELECT DISTINCT attack_range FROM heros;
-- 结果:近战、远程(只有2条记录)注意事项:
- DISTINCT 必须放在所有列名前面
- DISTINCT 对后面所有列名的组合进行去重
sql
-- 对 attack_range 和 name 的组合去重
SELECT DISTINCT attack_range, name FROM heros;
-- 结果:69条记录(因为每个英雄名称不同)ORDER BY 排序
基本排序
sql
-- 升序排序(默认)
SELECT name, hp_max FROM heros ORDER BY hp_max;
-- 降序排序
SELECT name, hp_max FROM heros ORDER BY hp_max DESC;多列排序
sql
-- 先按 mp_max 升序,再按 hp_max 降序
SELECT name, hp_max FROM heros ORDER BY mp_max, hp_max DESC;排序规则:
- 先按第一个列排序
- 第一个列值相同时,按第二个列排序
- 以此类推
排序要点
| 要点 | 说明 |
|---|---|
| 排序方向 | ASC 升序(默认),DESC 降序 |
| 排序字段 | 可以使用非选择列进行排序 |
| 位置 | ORDER BY 通常位于 SELECT 语句最后 |
| NULL 值 | 排序时 NULL 值通常排在最前面 |
文本排序
文本类型的排序规则:
- 根据数据库设置的字符集和排序规则
- 区分大小写取决于数据库配置
sql
-- 按名称排序
SELECT name FROM heros ORDER BY name;
-- 区分大小写排序(需要设置 BINARY)
SELECT name FROM heros ORDER BY BINARY name;LIMIT 约束返回结果
MySQL 语法
sql
-- 返回前 5 条记录
SELECT name, hp_max FROM heros ORDER BY hp_max DESC LIMIT 5;
-- 跳过前 3 条,返回接下来的 5 条
SELECT name, hp_max FROM heros ORDER BY hp_max DESC LIMIT 5 OFFSET 3;
-- 简写形式
SELECT name, hp_max FROM heros ORDER BY hp_max DESC LIMIT 3, 5;不同数据库语法
| 数据库 | 语法 |
|---|---|
| MySQL/PostgreSQL/SQLite | LIMIT n 或 LIMIT n OFFSET m |
| SQL Server/Access | TOP n |
| DB2 | FETCH FIRST n ROWS ONLY |
| Oracle | WHERE ROWNUM <= n |
各数据库示例:
sql
-- MySQL
SELECT name, hp_max FROM heros ORDER BY hp_max DESC LIMIT 5;
-- SQL Server
SELECT TOP 5 name, hp_max FROM heros ORDER BY hp_max DESC;
-- DB2
SELECT name, hp_max FROM heros ORDER BY hp_max DESC FETCH FIRST 5 ROWS ONLY;
-- Oracle
SELECT name, hp_max FROM heros WHERE ROWNUM <= 5 ORDER BY hp_max DESC;分页查询公式
sql
-- 第 pageIndex 页,每页 pageSize 条记录
SELECT * FROM heros
ORDER BY id
LIMIT pageSize OFFSET (pageIndex - 1) * pageSize;
-- 示例:第 2 页,每页 10 条
SELECT * FROM heros
ORDER BY id
LIMIT 10 OFFSET 10;SELECT 执行顺序
SQL 语句的执行顺序与书写顺序不同:
书写顺序:
sql
SELECT 列名
FROM 表名
WHERE 条件
GROUP BY 分组
HAVING 分组条件
ORDER BY 排序
LIMIT 限制;执行顺序:
code
1. FROM:确定数据来源
2. WHERE:过滤数据
3. GROUP BY:分组
4. HAVING:过滤分组
5. SELECT:选择列
6. DISTINCT:去重
7. ORDER BY:排序
8. LIMIT:限制结果理解执行顺序的重要性:
- WHERE 中不能使用 SELECT 中定义的别名
- GROUP BY 后才能使用聚合函数
- HAVING 用于过滤分组后的结果
sql
-- 错误:WHERE 中使用了 SELECT 别名
SELECT name, score * 2 AS double_score
FROM students
WHERE double_score > 180; -- 错误!
-- 正确:使用原表达式
SELECT name, score * 2 AS double_score
FROM students
WHERE score * 2 > 180;实用查询技巧
使用表达式
sql
-- 计算字段
SELECT name, hp_max + mp_max AS total FROM heros;
-- 使用函数
SELECT name, UPPER(name) AS upper_name FROM heros;条件表达式
sql
-- CASE WHEN
SELECT
name,
hp_max,
CASE
WHEN hp_max > 7000 THEN '高血量'
WHEN hp_max > 6000 THEN '中血量'
ELSE '低血量'
END AS hp_level
FROM heros;合并结果集
sql
-- UNION:合并并去重
SELECT name FROM heros WHERE role_main = '法师'
UNION
SELECT name FROM heros WHERE role_assist = '法师';
-- UNION ALL:合并不去重
SELECT name FROM heros WHERE role_main = '法师'
UNION ALL
SELECT name FROM heros WHERE role_assist = '法师';查询优化建议
避免使用 SELECT *
sql
-- 不推荐
SELECT * FROM heros;
-- 推荐:只查询需要的列
SELECT name, hp_max, mp_max FROM heros;合理使用索引
sql
-- 利用索引排序
SELECT name, hp_max FROM heros ORDER BY id;
-- 避免全表扫描
SELECT name FROM heros WHERE name LIKE '张%'; -- 可以使用索引
SELECT name FROM heros WHERE name LIKE '%张'; -- 无法使用索引限制返回结果
sql
-- 总是使用 LIMIT 限制结果数量
SELECT name, hp_max FROM heros ORDER BY hp_max DESC LIMIT 10;总结
核心语法
| 操作 | 语法 |
|---|---|
| 查询列 | SELECT 列1, 列2 FROM 表名 |
| 查询所有列 | SELECT * FROM 表名 |
| 起别名 | SELECT 列 AS 别名 FROM 表名 |
| 去重 | SELECT DISTINCT 列 FROM 表名 |
| 排序 | ORDER BY 列 [ASC|DESC] |
| 限制结果 | LIMIT n OFFSET m |
执行顺序
code
FROM → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT最佳实践
- 明确列名:避免使用
SELECT * - 合理排序:利用索引提高排序效率
- 限制结果:使用 LIMIT 避免返回过多数据
- 理解顺序:掌握 SQL 执行顺序,避免语法错误