{T}

检索数据

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条记录)

注意事项

  1. DISTINCT 必须放在所有列名前面
  2. 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;

排序规则

  1. 先按第一个列排序
  2. 第一个列值相同时,按第二个列排序
  3. 以此类推

排序要点

要点说明
排序方向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/SQLiteLIMIT nLIMIT n OFFSET m
SQL Server/AccessTOP n
DB2FETCH FIRST n ROWS ONLY
OracleWHERE 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

最佳实践

  1. 明确列名:避免使用 SELECT *
  2. 合理排序:利用索引提高排序效率
  3. 限制结果:使用 LIMIT 避免返回过多数据
  4. 理解顺序:掌握 SQL 执行顺序,避免语法错误