Jw
首页
技术
英语
首页
技术
英语
  • MySQL

    • MySQL 基础
    • 环境变量配置(PATH)
    • SQL 语法与分类
    • MySQL 数据类型
    • SQL - DDL 数据定义语言
    • SQL - DML 数据操作语言
    • SQL - DQL 数据查询语言
    • SQL - DCL 数据控制语言
    • MySQL 函数
    • SQL 约束
    • SQL 外键约束
    • 多表关系
    • 多表查询(连接查询)
    • 隐式内连接 vs 显式内连接
    • 子查询
    • 多表查询案例
    • 事务
    • 并发事务问题与隔离级别
    • MySQL 体系结构与存储引擎
    • 索引概述
    • 索引结构
    • 索引分类
    • 索引语法
    • SQL 性能分析
    • 索引使用
    • 索引设计原则
    • SQL 优化 - 插入数据与主键优化
    • SQL 优化 - order by 与 group by
    • SQL 优化 - limit / count / update
    • 视图
    • 存储过程
    • 存储过程 - 变量
    • 存储过程 - 流程控制、游标与条件处理
    • 存储函数
    • 触发器
    • 锁概述与全局锁
    • 表级锁
    • 行级锁
    • InnoDB 逻辑存储结构
    • InnoDB 架构
    • 事务原理(redo / undo log)
    • MVCC
    • MySQL 系统数据库
    • MySQL 常用工具
    • 数据备份与导入导出
    • 错误日志与二进制日志
    • 查询日志与慢查询日志
    • 主从复制 - 概述与原理
    • 主从复制 - 搭建
    • Mycat 配置
    • Mycat 垂直拆分与水平拆分
    • Mycat 分片规则
    • Mycat 管理与监控
    • Mycat 读写分离 - 一主一从
    • Mycat 读写分离 - 双主双从

SQL - DQL(数据查询语言)

DQL(Data Query Language)用来查询数据库表中的记录,查询关键字是 SELECT。 涵盖:基本查询、条件查询、聚合函数、分组查询、排序查询、分页查询。

一、完整语法与执行顺序

SELECT
    字段列表
FROM
    表名列表
WHERE
    条件列表
GROUP BY
    分组字段列表
HAVING
    分组后条件列表
ORDER BY
    排序字段列表
LIMIT
    分页参数;

执行顺序(与书写顺序不同):FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT

二、基本查询

-- 查询多个字段
SELECT 字段1, 字段2, ... FROM 表名;
SELECT * FROM 表名;

-- 设置别名(AS 可省略)
SELECT 字段1 [AS 别名1], 字段2 [AS 别名2] FROM 表名;

-- 去除重复记录
SELECT DISTINCT 字段列表 FROM 表名;
SELECT name, workno, age FROM emp;
SELECT * FROM emp;
SELECT workaddress AS '工作地址' FROM emp;
SELECT workaddress '工作地址' FROM emp;            -- AS 可省略
SELECT DISTINCT workaddress '工作地址' FROM emp;   -- 去重

三、条件查询

SELECT 字段列表 FROM 表名 WHERE 条件列表;

比较运算符

运算符功能
> >= < <=大于 / 大于等于 / 小于 / 小于等于
=等于
<> 或 !=不等于
BETWEEN ... AND ...在某个范围之内(含最小、最大值)
IN(...)在 in 之后的列表中的值,多选一
LIKE 占位符模糊匹配(_ 匹配单个字符,% 匹配任意个字符)
IS NULL是 NULL

逻辑运算符

运算符功能
AND 或 &&并且(多个条件同时成立)
OR 或 ||或者(多个条件任意一个成立)
NOT 或 !非,不是
SELECT * FROM emp WHERE age = 88;
SELECT * FROM emp WHERE age < 20;
SELECT * FROM emp WHERE age <= 20;
SELECT * FROM emp WHERE idcard IS NULL;          -- 没有身份证号
SELECT * FROM emp WHERE idcard IS NOT NULL;      -- 有身份证号
SELECT * FROM emp WHERE age != 88;
SELECT * FROM emp WHERE age <> 88;               -- 同上,两种写法等价
SELECT * FROM emp WHERE age BETWEEN 15 AND 20;   -- 15 ~ 20(含两端)
SELECT * FROM emp WHERE age >= 15 && age <= 20;  -- 等价写法
SELECT * FROM emp WHERE age < 25 && gender = '女';
SELECT * FROM emp WHERE age IN (18, 20, 40);
SELECT * FROM emp WHERE name LIKE '__';          -- 两个字的姓名
SELECT * FROM emp WHERE idcard LIKE '%X';        -- 身份证最后一位是 X
SELECT * FROM emp WHERE idcard LIKE '_________________X';  -- 前 17 位任意、最后 X
  • 判断空值不能写 = NULL,只能用 IS NULL / IS NOT NULL;
  • BETWEEN a AND b 包含两端;
  • 字符串与日期值要加引号。

四、聚合函数

将一列数据作为一个整体进行纵向计算。

函数功能
COUNT统计数量
MAX最大值
MIN最小值
AVG平均值
SUM求和
SELECT 聚合函数(字段列表) FROM 表名;
SELECT COUNT(idcard) FROM emp;   -- 统计员工数量
SELECT AVG(age) FROM emp;        -- 平均年龄
SELECT MAX(age) FROM emp;        -- 最大年龄
SELECT MIN(age) FROM emp;        -- 最小年龄
SELECT SUM(age) FROM emp WHERE workaddress = '西安';  -- 西安地区员工年龄之和

NULL 值不参与所有聚合函数的运算:COUNT(*) 统计所有行,COUNT(字段) 不统计该字段为 NULL 的行。

五、分组查询

SELECT 字段列表 FROM 表名 [WHERE 条件] GROUP BY 分组字段名 [HAVING 分组后过滤条件];

WHERE 与 HAVING 的区别

WHEREHAVING
执行时机分组之前过滤,不满足条件的不参与分组分组之后对结果过滤
判断条件不能对聚合函数判断可以对聚合函数判断
  • 执行顺序:WHERE > 聚合函数 > HAVING;
  • 分组之后,查询的字段一般为聚合函数和分组字段,查其他字段没有意义。
-- 按性别分组,统计男、女员工的数量
SELECT gender, COUNT(*) FROM emp GROUP BY gender;

-- 按性别分组,统计男、女员工的平均年龄
SELECT gender, AVG(age) FROM emp GROUP BY gender;

-- 年龄小于 45 的员工按工作地址分组,取员工数 >= 3 的工作地址
SELECT workaddress, COUNT(*) FROM emp WHERE age < 45 GROUP BY workaddress HAVING COUNT(*) >= 3;

-- HAVING 中也可用聚合结果的别名
SELECT workaddress, COUNT(*) AS address_count FROM emp WHERE age < 45 GROUP BY workaddress HAVING address_count >= 3;

六、排序查询

SELECT 字段列表 FROM 表名 ORDER BY 字段1 排序方式1, 字段2 排序方式2;
  • ASC:升序(默认值)
  • DESC:降序
  • 多字段排序时,前一个字段值相同才会按后一个字段排序;
  • ORDER BY 可以使用字段别名或表别名。
SELECT * FROM emp ORDER BY age ASC;
SELECT * FROM emp ORDER BY age;                    -- 默认升序
SELECT * FROM emp ORDER BY entrydate DESC;         -- 按入职时间降序
SELECT * FROM emp ORDER BY age, entrydate DESC;    -- 年龄升序,年龄相同按入职时间降序

-- 表别名 + 字段别名排序
SELECT e.name ename, e.age eage FROM emp e WHERE e.age > 15 ORDER BY eage;

七、分页查询

SELECT 字段列表 FROM 表名 LIMIT 起始索引, 查询记录数;
  • 起始索引从 0 开始:起始索引 = (查询页码 - 1) * 每页显示记录数;
  • 分页查询是数据库的方言,不同数据库实现不同,MySQL 中是 LIMIT;
  • 查第一页时起始索引可省略,直接写 LIMIT 10。
SELECT * FROM emp LIMIT 0, 10;   -- 第 1 页,每页 10 条
SELECT * FROM emp LIMIT 10;      -- 同上,首页可省略起始索引
SELECT * FROM emp LIMIT 10, 10;  -- 第 2 页,每页 10 条

八、综合练习

-- 1. 查询年龄为 20、21、22、23 的女性员工信息
SELECT * FROM emp WHERE gender = '女' && age IN (20, 21, 22, 23);

-- 2. 查询性别为男、年龄在 20-40(含)以内、且姓名为三个字的员工
SELECT * FROM emp WHERE gender = '男' && age BETWEEN 20 AND 40 && name LIKE '___';

-- 3. 统计年龄小于 60 的男性员工和女性员工的人数
SELECT gender, COUNT(*) FROM emp WHERE age < 60 GROUP BY gender;

-- 4. 查询年龄小于 35 的员工的姓名和年龄,按年龄升序,年龄相同按入职时间降序
SELECT name, age, entrydate FROM emp WHERE age < 35 ORDER BY age, entrydate DESC;

-- 5. 查询性别为男、年龄 20-40(含)以内的前 5 个员工,按年龄升序,年龄相同按入职时间升序
SELECT * FROM emp WHERE gender = '男' && age BETWEEN 20 AND 40 ORDER BY age, entrydate LIMIT 5;

九、速查总结

-- 单表查询骨架(书写顺序,[] 内为可选)
SELECT [DISTINCT] 字段列表 [AS 别名]
FROM 表名
[WHERE 条件]                              -- 分组前过滤,不能判断聚合函数
[GROUP BY 分组字段 [HAVING 分组后条件]]    -- 分组后过滤,可判断聚合函数
[ORDER BY 字段 [ASC | DESC], ...]         -- 默认 ASC,多字段依次生效
[LIMIT 起始索引, 记录数];                  -- 起始索引 = (页码 - 1) * 每页记录数
环节关键字关键点
基本查询SELECT / DISTINCT / AS别名 AS 可省略;DISTINCT 去重
条件过滤WHEREIS NULL、BETWEEN a AND b(含两端)、IN(...)、LIKE(_ 单字符 / % 任意字符)
聚合COUNT / MAX / MIN / AVG / SUMNULL 不参与运算,COUNT(*) 统计所有行
分组GROUP BY / HAVINGWHERE 分组前、HAVING 分组后且可判断聚合函数
排序ORDER BY默认 ASC;可用字段别名排序
分页LIMIT起始索引从 0 开始,查第一页可省略

执行顺序:FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT

相关

  • SQL 语法与分类:书写规范 + DDL / DML / DQL / DCL
  • SQL - DDL:建库、建表、改表、删表
  • SQL - DML:增删改数据
  • MySQL 数据类型:数值 / 字符串 / 日期时间
最近更新: 2026/10/6 18:09
Contributors: liujw
Prev
SQL - DML 数据操作语言
Next
SQL - DCL 数据控制语言