DML
目的
在MySQL管理软件中,DDL(数据定义语言)已完成数据库、表结构的定义,而DML(数据操纵语言)的核心作用是对表中的数据进行日常管理与操作,主要包含三类核心指令,对应数据的增、删、改操作,具体如下:
INSERT:实现数据的插入
DELETE:实现数据的删除
UPDATE:实现数据的更新
插入数据(INSERT)
INSERT用于向数据表中插入一条或多条新数据,核心分为“完整插入”“部分插入”,同时支持批量插入,适配不同运维场景,语法需严格遵循字段数量、数据类型与表结构一致的原则。
完整插入
适用于向表中所有字段插入数据,无需指定字段名,但VALUES后的数值顺序、数量、类型必须与表结构定义完全匹配(若字段有默认值或允许为空,也可省略对应数值,用DEFAULT填充)。
-- 语法
INSERT INTO 表名 VALUES (值1, 值2, 值3…值n);
示例:向student表(字段:id、name、age)插入一条完整数据
mysql> INSERT INTO student VALUES (1, '张三', 20);
部分插入
适用于仅向表中指定字段插入数据,需明确指定字段名,未指定的字段需满足“有默认值”或“允许为空”,否则插入失败。
-- 语法
INSERT INTO 表名 (列名1, 列名2, ...) VALUES (值1, 值2, ...);
示例:向student表仅插入id和name字段的数据
mysql> INSERT INTO student (id, name) VALUES (2, '李四');
批量插入(实战重点)
运维中高频使用,用于一次性插入多条数据,比单条多次插入效率更高,减少数据库连接开销。
-- 语法
INSERT INTO 表名 (列名1, 列名2, ...) VALUES (值1, 值2, ...), (值1, 值2, ...), ...;
示例:向student表批量插入3条数据
mysql> INSERT INTO student (id, name, age) VALUES (3, '王五', 21), (4, '赵六', 19), (5, '孙七', 22);
插入注意事项
数值类型(int、float等)插入时无需加引号,字符串类型(varchar、char等)必须加单引号(推荐)或双引号。
字段与对应数值的数量、数据类型必须一致,否则会报语法错误。
若表中存在主键(PRIMARY KEY),插入数据时主键值不可重复,否则插入失败。
启用严格SQL模式时,未指定字段且无默认值、不允许为空的情况下,插入会报错;非严格模式下会自动填充默认值(如空字符串、0)。
更新数据(UPDATE)
UPDATE用于修改表中已存在的数据,核心是通过WHERE子句指定修改范围,若省略WHERE子句,会修改表中所有数据(运维高危操作,需谨慎)。
基础语法
-- 单字段更新
UPDATE 表名 SET 列名1 = 值1 WHERE 条件;
-- 多字段更新
UPDATE 表名 SET 列名1 = 值1, 列名2 = 值2, ... WHERE 条件;
实战示例
示例1:单字段更新
-- 准备数据表
mysql> CREATE TABLE t6 (id int, name varchar(20));
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO t6 VALUES (1, 'aa'), (2, 'bb');
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from t6;
+------+------+
| id | name |
+------+------+
| 1 | aa |
| 2 | bb |
+------+------+
2 rows in set (0.00 sec)
-- 需求:将id=2的name值从'bb'修改为'cc'
mysql> UPDATE t6 SET name = 'cc' WHERE id = 2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
-- 查看更新结果
mysql> select * from t6;
+------+------+
| id | name |
+------+------+
| 1 | aa |
| 2 | cc |
+------+------+
2 rows in set (0.00 sec)
示例2:多字段更新
-- 需求:将id=1的id改为3,name改为'aaa',同时添加age字段(假设表已新增age字段)并赋值20
mysql> UPDATE t6 SET id = 3, name = 'aaa' WHERE id = 1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from t6;
+------+------+
| id | name |
+------+------+
| 3 | aaa |
| 2 | cc |
+------+------+
2 rows in set (0.00 sec)
示例3:修改root账户密码
-- 1. MySQL 5.7 版本(兼容旧写法,不推荐)
mysql> UPDATE mysql.user SET authentication_string = PASSWORD('Abc@6666') WHERE user = 'root';
Query OK, 1 row affected, 1 warning (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 1
-- 2. 刷新权限(修改密码后必做,使配置生效)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)
更新注意事项
严禁省略WHERE子句,否则会批量修改全表数据(如UPDATE t6 SET name = ‘cc’会修改t6表所有行的name值),建议操作前先执行SELECT语句校验范围(如SELECT * FROM t6 WHERE id = 2)。
修改主键、外键字段时,需先确认无关联数据冲突(如外键字段值不可修改为不存在的关联主键值)。
可配合ORDER BY和LIMIT限制更新范围(如UPDATE t6 SET name = ‘cc’ ORDER BY id DESC LIMIT 1,仅修改id最大的一行)。
修改密码后必须执行FLUSH PRIVILEGES刷新权限,否则修改不生效。
数据(DELETE)
DELETE用于删除表中已存在的数据,同样通过WHERE子句指定删除范围,省略WHERE子句会删除全表数据(可通过事务回滚恢复,区别于TRUNCATE),属于DML操作。
基础语法
DELETE FROM 表名 WHERE 条件;
实战示例
-- 需求:删除t6表中id=2的记录
mysql> DELETE FROM t6 WHERE id = 2;
Query OK, 1 row affected (0.00 sec)
-- 查看删除结果
mysql> select * from t6;
+------+------+
| id | name |
+------+------+
| 3 | aaa |
+------+------+
1 row in set (0.00 sec)
关键补充:DELETE与TRUNCATE的区别
运维中常需清空表数据,需根据场景选择DELETE或TRUNCATE,核心区别如下(结合实战场景说明):
| 对比维度 | DELETE | TRUNCATE |
|---|---|---|
| 操作类型 | DML(数据操纵语言) | DDL(数据定义语言) |
| 执行机制 | 逐行删除,记录undo log和binlog(可回滚) | 直接释放数据页,重建空表(不逐行删除) |
| WHERE子句 | 支持,可精准删除部分数据 | 不支持,只能清空全表 |
| 自增主键 | 不重置,下次插入延续上次最大值 | 重置为初始值(通常为1) |
| 事务支持 | 支持,可通过ROLLBACK回滚 | 多数场景下不可回滚(隐式提交) |
| 触发器 | 会触发DELETE触发器 | 不触发任何触发器 |
| 权限要求 | 需DELETE权限 | 需DROP权限 |
| 适用场景 | 删除部分数据、需回滚、需触发触发器 | 快速清空全表、测试环境重置数据 |
删除注意事项(运维高危提醒)
省略WHERE子句的后果:删除表中所有数据(如DELETE FROM t6),但表结构保留,可通过事务回滚恢复(需未提交事务),大表删除会产生大量日志,影响性能。
删除前必须备份数据(如执行CREATE TABLE t6_backup AS SELECT * FROM t6),避免误删无法恢复。
删除关联表数据时,需先删除子表(外键关联表)数据,再删除主表数据,否则会报外键冲突错误;若需快速清空,可先禁用外键检查(SET foreign_key_checks = 0;),操作后恢复(SET foreign_key_checks = 1;)。
大表删除建议:避免使用DELETE(逐行删除慢),优先使用TRUNCATE(若无需保留自增),或分批删除(如DELETE FROM t6 WHERE id < 1000 LIMIT 100),减少锁占用。
总结
DML核心是对数据的“增、删、改”,三者均为MySQL DBA运维高频操作,重点注意:
INSERT:保证字段与数值匹配,批量插入提升效率,注意主键唯一。
UPDATE:建议不要省略WHERE。
DELETE:谨慎使用无WHERE删除,区分DELETE与TRUNCATE的适用场景,删除前建议备份。
DQL
目的
在MySQL管理软件中,DDL定义数据库结构、DML实现数据的增删改操作,而DQL(数据查询语言)的核心作用是通过SELECT语句,从数据表中精准获取所需数据,支撑各类业务场景的查询需求。例如互联网场景中,用户查询个人余额、游戏玩家查询账号装备、电商用户查询商品信息等,本质上都是通过DQL语句实现的,是MySQL DBA运维和业务落地中最常用的SQL语言之一。
基础环境准备
素材1
先创建一张基础数据表t3,包含序号、姓名、年龄三列信息,建表语句如下:
-- 语法:创建t3表,包含3列信息
create table t3 (id int, name varchar(20), age int);
向t3表插入以下测试数据:
insert into t3 values (1,"zhangsan",23);
insert into t3 values (2,"lisi",24);
insert into t3 values (3,"wangwu",18);
素材2
依据下图准备素材:
- company 公司
- department 部门
- employee 员工

步骤1:创建company数据库
-- 语法:创建company数据库(用于存储员工相关数据)
mysql> create database company;
步骤2:创建employee5员工表(指定表结构及约束)
-- 语法:在company数据库下创建employee5表,定义员工相关字段及约束
mysql> CREATE TABLE company.employee5(
id int primary key AUTO_INCREMENT not null, -- 主键,自增,非空(员工编号)
name varchar(30) not null, -- 员工姓名,非空
sex enum('male','female') default 'male' not null, -- 性别,枚举类型,默认男性,非空
hire_date date not null, -- 入职日期,非空
post varchar(50) not null, -- 岗位,非空
job_description varchar(100), -- 岗位职责,可空
salary double(15,2) not null, -- 薪资,双精度浮点型,非空(保留2位小数)
office int, -- 办公室编号,可空
dep_id int -- 部门编号,可空
);
步骤3:查看employee5表结构(验证表创建正确性)
-- 语法:查看employee5表的字段、类型、约束等结构信息
mysql> desc employee5;
+-----------------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+-----------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(30) | NO | | NULL | |
| sex | enum('male','female') | NO | | male | |
| hire_date | date | NO | | NULL | |
| post | varchar(50) | NO | | NULL | |
| job_description | varchar(100) | YES | | NULL | |
| salary | double(15,2) | NO | | NULL | |
| office | int(11) | YES | | NULL | |
| dep_id | int(11) | YES | | NULL | |
+-----------------+-----------------------+------+-----+---------+----------------+
9 rows in set (0.00 sec)
步骤4:向employee5表插入员工数据(批量插入,贴合企业实操)
-- 语法:向company.employee5表指定字段批量插入员工数据,适配表结构约束
mysql> insert into company.employee5(name,sex,hire_date,post,job_description,salary,office,dep_id) values
('jack','male','20180202','instructor','teach',5000,501,100),
('tom','male','20180203','instructor','teach',5500,501,100),
('robin','male','20180202','instructor','teach',8000,501,100),
('alice','female','20180202','instructor','teach',7200,501,100),
('aofa','male','20180202','hr','hrcc',600,502,101),
('harry','male','20180202','hr',NULL,6000,502,101),
('emma','female','20180206','sale','salecc',20000,503,102),
('christine','female','20180205','sale','salecc',2200,503,102),
('zhuzhu','male','20180205','sale',NULL,2200,503,102),
('gougou','male','20180205','sale','',2200,503,102);
-- 查看全部数据
mysql> select * from employee5;
+----+-----------+--------+------------+------------+-----------------+----------+--------+--------+
| id | name | sex | hire_date | post | job_description | salary | office | dep_id |
+----+-----------+--------+------------+------------+-----------------+----------+--------+--------+
| 1 | jack | male | 2018-02-02 | instructor | teach | 5000.00 | 501 | 100 |
| 2 | tom | male | 2018-02-03 | instructor | teach | 5500.00 | 501 | 100 |
| 3 | robin | male | 2018-02-02 | instructor | teach | 8000.00 | 501 | 100 |
| 4 | alice | female | 2018-02-02 | instructor | teach | 7200.00 | 501 | 100 |
| 5 | aofa | male | 2018-02-02 | hr | hrcc | 600.00 | 502 | 101 |
| 6 | harry | male | 2018-02-02 | hr | NULL | 6000.00 | 502 | 101 |
| 7 | emma | female | 2018-02-06 | sale | salecc | 20000.00 | 503 | 102 |
| 8 | christine | female | 2018-02-05 | sale | salecc | 2200.00 | 503 | 102 |
| 9 | zhuzhu | male | 2018-02-05 | sale | NULL | 2200.00 | 503 | 102 |
| 10 | gougou | male | 2018-02-05 | sale | | 2200.00 | 503 | 102 |
+----+-----------+--------+------------+------------+-----------------+----------+--------+--------+
10 rows in set (0.00 sec)
补充说明:employee5表包含主键自增、枚举约束、非空约束等常用配置,插入数据时包含了非空值、NULL值、空字符串等场景,后续可基于此表开展多条件查询、聚合查询等DQL进阶实操,贴合MySQL DBA日常运维中的员工数据管理场景。
MySQL查询
简单查询(DQL基础实操)
简单查询是DQL最基础的用法,核心用于快速获取表中数据,无需复杂条件,重点掌握“全列查询”和“四则运算查询”,贴合日常运维快速校验数据的场景
查看所有列(全列查询)
核心语法为SELECT * FROM 表名;,用于查询表中所有字段的数据,实操需注意查询前提:
- 前提1:若已进入目标数据库(如company数据库),可直接执行查询语句,无需指定库名;
- 前提2:若未进入目标数据库,查询时需在表名前加上库名(格式:库名.表名),避免报“表不存在”错误。
-- 实操步骤1:进入company数据库
mysql> use company;
-- 实操步骤2:查询employee5表所有列数据
mysql> SELECT * FROM employee5;
-- 补充:未进入company数据库,查询所有列(完整写法,指定库名)
mysql> SELECT * FROM company.employee5;
说明:查询结果会显示employee5表中所有员工的id、name、sex、salary等全部字段数据,适合快速查看表中所有数据概况(大表不推荐使用,效率较低)。
四则运算查询
DQL支持对数值类型字段进行四则运算(+、-、*、/),常用于基于表中现有数值计算衍生数据,例如通过员工月薪(salary)计算年薪(月薪×12),示例如下:
-- 需求:查询employee5表中所有员工的姓名、月薪、年薪(年薪=月薪×12)
-- 语法:SELECT 字段1, 字段2, 数值字段 四则运算 FROM 表名;
mysql> SELECT name, salary, salary*12 FROM employee5;
+-----------+----------+-----------+
| name | salary | salary*12 |
+-----------+----------+-----------+
| jack | 5000.00 | 60000.00 |
| tom | 5500.00 | 66000.00 |
| robin | 8000.00 | 96000.00 |
| alice | 7200.00 | 86400.00 |
| aofa | 600.00 | 7200.00 |
| harry | 6000.00 | 72000.00 |
| emma | 20000.00 | 240000.00 |
| christine | 2200.00 | 26400.00 |
| zhuzhu | 2200.00 | 26400.00 |
| gougou | 2200.00 | 26400.00 |
+-----------+----------+-----------+
10 rows in set (0.01 sec)
查询结果说明:
- 结果会显示三列数据:name(员工姓名)、salary(原月薪)、salary*12(计算出的年薪);
- 若数值字段存在NULL值,四则运算结果也会为NULL(如无薪资数据的员工,年薪会显示NULL);
- 可灵活调整运算逻辑,例如查询月薪扣除1000后的金额:SELECT name, salary, salary-1000 FROM employee5;
简单查询注意事项
- 全列查询(SELECT *)仅适合小表快速校验数据,大表需避免使用,优先指定所需字段,提升查询效率;
- 未进入目标数据库时,必须加上“库名.表名”的格式,否则MySQL会默认在当前数据库中查找表,导致查询失败;
- 四则运算仅适用于数值类型字段(如salary、age等),对字符串类型字段(如name、post)执行四则运算会报语法错误或返回无效结果;
条件查询(DQL核心实操)
条件查询是DQL中最常用的查询方式,核心通过WHERE子句指定查询条件,精准筛选所需数据,适配各类业务筛选场景(如筛选特定部门、特定薪资的员工)。以下基于company.employee5表,结合实操场景,讲解常用条件查询语法及示例。
单条件查询(WHERE)
核心语法:通过WHERE子句指定一个查询条件,筛选符合条件的记录,适用于简单筛选场景。
-- 需求:查询hr部门的员工姓名(仅筛选post为hr的记录)
mysql> SELECT name,post
-> FROM employee5
-> WHERE post='hr';
+-------+------+
| name | post |
+-------+------+
| aofa | hr |
| harry | hr |
+-------+------+
2 rows in set (0.01 sec)
说明:WHERE后紧跟条件,字符串类型条件(如’hr’)需加单引号,字段名(post)与表结构保持一致,否则筛选失败。
多条件查询(AND/OR)
当需要多个条件共同筛选时,使用AND(逻辑与)、OR(逻辑或)连接多个条件,AND表示“同时满足”,OR表示“满足任一条件”。
-- 示例1:AND用法(同时满足两个条件)
-- 需求:查询hr部门的员工姓名,并且工资大于1000
mysql> SELECT name,salary
-> FROM employee5
-> WHERE post='hr' AND salary>1000;
+-------+---------+
| name | salary |
+-------+---------+
| harry | 6000.00 |
+-------+---------+
1 row in set (0.00 sec)
-- 示例2:OR用法(满足任一条件即可)
-- 需求:查询所有部门的员工姓名,并且工资是6000或者8000的员工
mysql> SELECT name, salary FROM employee5
-> WHERE salary=6000 OR salary=8000;
+-------+---------+
| name | salary |
+-------+---------+
| robin | 8000.00 |
| harry | 6000.00 |
+-------+---------+
2 rows in set (0.00 sec)
注意:当AND和OR同时使用时,需用括号区分优先级,避免筛选结果异常。
范围查询(BETWEEN AND / NOT BETWEEN AND)
用于筛选数值、日期等类型字段在指定范围内的记录,BETWEEN AND 表示“在某个区间内(包含边界值)”,NOT BETWEEN AND 表示“不在某个区间内”。
-- 示例1:BETWEEN AND(包含5000和15000两个边界值)
-- 需求:查询薪资在5000到15000的员工姓名和薪资
mysql> SELECT name,salary FROM employee5
-> WHERE salary BETWEEN 5000 AND 15000;
+-------+---------+
| name | salary |
+-------+---------+
| jack | 5000.00 |
| tom | 5500.00 |
| robin | 8000.00 |
| alice | 7200.00 |
| harry | 6000.00 |
+-------+---------+
5 rows in set (0.00 sec)
-- 示例2:NOT BETWEEN AND(不包含边界值)
-- 需求:查询薪资不在5000~15000的员工姓名和薪资
mysql> SELECT name,salary FROM employee5
-> WHERE salary NOT BETWEEN 5000 AND 15000;
+-----------+----------+
| name | salary |
+-----------+----------+
| aofa | 600.00 |
| emma | 20000.00 |
| christine | 2200.00 |
| zhuzhu | 2200.00 |
| gougou | 2200.00 |
+-----------+----------+
5 rows in set (0.00 sec)
补充:BETWEEN AND 等价于 “字段 >= 最小值 AND 字段 <= 最大值”,实操中可根据习惯选择。
集合查询(IN / NOT IN)
用于筛选字段值在指定集合内(或不在集合内)的记录,适用于多个离散值的筛选,相比OR连接多个条件,IN语法更简洁、效率更高。
-- 方式1:OR连接(多条件筛选,效率较低)
mysql> SELECT name, salary FROM employee5
-> WHERE salary=4000 OR salary=5000 OR salary=6000 OR salary=9000 ;
+-------+---------+
| name | salary |
+-------+---------+
| jack | 5000.00 |
| harry | 6000.00 |
+-------+---------+
2 rows in set (0.00 sec)
-- 方式2:IN优化(语法简洁,效率更高,推荐使用)
-- 需求:查询薪资是4000、5000、6000、9000中任一值的员工
mysql> SELECT name, salary FROM employee5
-> WHERE salary IN (4000,5000,6000,9000) ;
+-------+---------+
| name | salary |
+-------+---------+
| jack | 5000.00 |
| harry | 6000.00 |
+-------+---------+
2 rows in set (0.00 sec)
-- 示例3:NOT IN(筛选不在指定集合内的记录)
-- 需求:查询薪资不是4000、5000、6000、9000的员工
mysql> SELECT name, salary FROM employee5
-> WHERE salary NOT IN (4000,5000,6000,9000) ;
+-----------+----------+
| name | salary |
+-----------+----------+
| tom | 5500.00 |
| robin | 8000.00 |
| alice | 7200.00 |
| aofa | 600.00 |
| emma | 20000.00 |
| christine | 2200.00 |
| zhuzhu | 2200.00 |
| gougou | 2200.00 |
+-----------+----------+
8 rows in set (0.00 sec)
注意:IN和NOT IN 内的集合元素需与字段数据类型一致,若集合内有NULL值,会导致查询结果异常。
空值查询(IS NULL / IS NOT NULL)
用于筛选字段值为NULL(空值)或非NULL(非空值)的记录,需注意:NULL表示“无数据”,与空字符串(”)、0 不同,不能用“=”“!=”判断,必须用IS NULL / IS NOT NULL。
-- 示例1:IS NULL(筛选字段值为NULL的记录)
-- 需求:查询没有岗位描述(job_description为NULL)的员工
mysql> SELECT name,job_description FROM employee5
-> WHERE job_description IS NULL;
+--------+-----------------+
| name | job_description |
+--------+-----------------+
| harry | NULL |
| zhuzhu | NULL |
+--------+-----------------+
2 rows in set (0.00 sec)
-- 示例2:IS NOT NULL(筛选字段值非NULL的记录)
-- 需求:查询有岗位描述的员工
mysql> SELECT name,job_description FROM employee5
-> WHERE job_description IS NOT NULL;
+-----------+-----------------+
| name | job_description |
+-----------+-----------------+
| jack | teach |
| tom | teach |
| robin | teach |
| alice | teach |
| aofa | hrcc |
| emma | salecc |
| christine | salecc |
| gougou | |
+-----------+-----------------+
8 rows in set (0.00 sec)
-- 错误示范:用“=”判断NULL值(无查询结果,语法错误)
mysql> SELECT name,job_description FROM employee5
-> WHERE job_description='';
+--------+-----------------+
| name | job_description |
+--------+-----------------+
| gougou | |
+--------+-----------------+
1 row in set (0.00 sec)
说明:空字符串(”)是“有数据但为空”,NULL是“无数据”,二者本质不同,筛选时需区分清楚。
模糊查询(LIKE)
用于模糊匹配字符串类型字段,常搭配通配符使用,适用于“不确定完整字段值”的筛选场景(如模糊查询姓名、商品名),MySQL中常用通配符有两种:
- %:代表0个、1个或多个任意字符(注意:不同于shell中的“*”星号);
- _:代表1个任意字符(注意:不同于shell中的“?”问号)。
-- 示例1:搭配%通配符(模糊匹配以“al”开头的姓名)
-- 需求:查询姓名以“al”开头的员工(如alice)
mysql> SELECT * FROM employee5
-> WHERE name LIKE 'al%';
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
| id | name | sex | hire_date | post | job_description | salary | office | dep_id |
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
| 4 | alice | female | 2018-02-02 | instructor | teach | 7200.00 | 501 | 100 |
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
1 row in set (0.00 sec)
-- 示例2:搭配_通配符(模糊匹配以“al”开头、后面跟3个任意字符的姓名)
-- 需求:查询姓名以“al”开头,且姓名长度为5的员工(alice:al+3个字符)
mysql> SELECT * FROM employee5
-> WHERE name LIKE 'al___';
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
| id | name | sex | hire_date | post | job_description | salary | office | dep_id |
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
| 4 | alice | female | 2018-02-02 | instructor | teach | 7200.00 | 501 | 100 |
+----+-------+--------+------------+------------+-----------------+---------+--------+--------+
1 row in set (0.01 sec)
补充:LIKE查询区分大小写(取决于数据库排序规则),若需不区分大小写,可搭配LOWER()、UPPER()函数使用(如WHERE LOWER(name) LIKE ‘al%’)。
条件查询注意事项
- 条件查询的核心是WHERE子句,所有筛选条件均需跟在WHERE后,多个条件用AND/OR连接;
- 字符串类型、日期类型的条件必须加单引号,数值类型无需加引号;
- NULL值只能用IS NULL / IS NOT NULL判断,不能用“=”“!=”;
- LIKE模糊查询中,%和_的用法需与shell通配符区分,避免混淆;
- 大范围筛选(如薪资>5000)时,若字段有索引,查询效率会大幅提升。
查询排序
查询排序是DQL实操中高频用法,核心通过ORDER BY子句对查询结果按指定字段排序,搭配LIMIT子句可限制查询结果的条数(如筛选topN数据),适配“按薪资排序”“取排名靠前数据”等业务场景,以下基于company.employee5表展开实操。
基础排序(ASC 升序 / DESC 降序)
ORDER BY 后指定排序字段,搭配排序关键字,可实现升序或降序排列,核心语法及示例如下:
- ASC:升序排列(默认排序方式,可省略不写),即从最小值到最大值;
- DESC:降序排列,即从最大值到最小值。
-- 示例1:按工资升序排列(从小到大,省略ASC也可生效)
-- 需求:查询所有员工信息,按薪资升序排列
mysql> SELECT * FROM employee5 ORDER BY salary ASC;
+----+-----------+--------+------------+------------+-----------------+----------+--------+--------+
| id | name | sex | hire_date | post | job_description | salary | office | dep_id |
+----+-----------+--------+------------+------------+-----------------+----------+--------+--------+
| 5 | aofa | male | 2018-02-02 | hr | hrcc | 600.00 | 502 | 101 |
| 8 | christine | female | 2018-02-05 | sale | salecc | 2200.00 | 503 | 102 |
| 9 | zhuzhu | male | 2018-02-05 | sale | NULL | 2200.00 | 503 | 102 |
| 10 | gougou | male | 2018-02-05 | sale | | 2200.00 | 503 | 102 |
| 1 | jack | male | 2018-02-02 | instructor | teach | 5000.00 | 501 | 100 |
| 2 | tom | male | 2018-02-03 | instructor | teach | 5500.00 | 501 | 100 |
| 6 | harry | male | 2018-02-02 | hr | NULL | 6000.00 | 502 | 101 |
| 4 | alice | female | 2018-02-02 | instructor | teach | 7200.00 | 501 | 100 |
| 3 | robin | male | 2018-02-02 | instructor | teach | 8000.00 | 501 | 100 |
| 7 | emma | female | 2018-02-06 | sale | salecc | 20000.00 | 503 | 102 |
+----+-----------+--------+------------+------------+-----------------+----------+--------+--------+
10 rows in set (0.00 sec)
-- 示例2:按工资降序排列(从大到小,必须写DESC)
-- 需求:查询所有员工信息,按薪资降序排列
mysql> SELECT * FROM employee5 ORDER BY salary DESC;
+----+-----------+--------+------------+------------+-----------------+----------+--------+--------+
| id | name | sex | hire_date | post | job_description | salary | office | dep_id |
+----+-----------+--------+------------+------------+-----------------+----------+--------+--------+
| 7 | emma | female | 2018-02-06 | sale | salecc | 20000.00 | 503 | 102 |
| 3 | robin | male | 2018-02-02 | instructor | teach | 8000.00 | 501 | 100 |
| 4 | alice | female | 2018-02-02 | instructor | teach | 7200.00 | 501 | 100 |
| 6 | harry | male | 2018-02-02 | hr | NULL | 6000.00 | 502 | 101 |
| 2 | tom | male | 2018-02-03 | instructor | teach | 5500.00 | 501 | 100 |
| 1 | jack | male | 2018-02-02 | instructor | teach | 5000.00 | 501 | 100 |
| 8 | christine | female | 2018-02-05 | sale | salecc | 2200.00 | 503 | 102 |
| 9 | zhuzhu | male | 2018-02-05 | sale | NULL | 2200.00 | 503 | 102 |
| 10 | gougou | male | 2018-02-05 | sale | | 2200.00 | 503 | 102 |
| 5 | aofa | male | 2018-02-02 | hr | hrcc | 600.00 | 502 | 101 |
+----+-----------+--------+------------+------------+-----------------+----------+--------+--------+
10 rows in set (0.00 sec)
说明:排序字段需与表中字段名一致(如薪资字段为salary),若排序字段为字符串类型(如name),则按字符编码顺序排序(如字母顺序、汉字拼音顺序)。
限制查询结果条数(LIMIT,结合排序实战)
LIMIT 用于限制查询结果的行数,常与ORDER BY 搭配使用,实现“筛选排序后前N条数据”的需求(如查询薪资最高的前五名员工),核心语法如下:
-- 语法:ORDER BY 排序字段 排序方式 LIMIT 条数;(默认初始位置为0,可省略)
SELECT * FROM 表名 ORDER BY 字段名 DESC/ASC LIMIT 数量;
示例:
-- 需求:查询employee5表中工资最高的前五名员工(先降序排序,再取前5条)
mysql> SELECT * FROM employee5 ORDER BY salary DESC LIMIT 5;
+----+-------+--------+------------+------------+-----------------+----------+--------+--------+
| id | name | sex | hire_date | post | job_description | salary | office | dep_id |
+----+-------+--------+------------+------------+-----------------+----------+--------+--------+
| 7 | emma | female | 2018-02-06 | sale | salecc | 20000.00 | 503 | 102 |
| 3 | robin | male | 2018-02-02 | instructor | teach | 8000.00 | 501 | 100 |
| 4 | alice | female | 2018-02-02 | instructor | teach | 7200.00 | 501 | 100 |
| 6 | harry | male | 2018-02-02 | hr | NULL | 6000.00 | 502 | 101 |
| 2 | tom | male | 2018-02-03 | instructor | teach | 5500.00 | 501 | 100 |
+----+-------+--------+------------+------------+-----------------+----------+--------+--------+
5 rows in set (0.00 sec)
补充说明:
- LIMIT 后仅跟一个数字时,表示“取排序后前N条数据”,初始位置默认从0开始(无需额外指定);
- 若需取“从第M条开始,取N条数据”,可写为 LIMIT M, N(如 LIMIT 5, 3 表示从第6条开始,取3条数据);
- LIMIT 仅在MySQL中生效,其他数据库(如Oracle)用法不同,实操需注意数据库适配。
查询排序注意事项
- 排序与LIMIT的顺序:必须先写ORDER BY 排序,再写LIMIT 限制条数,顺序颠倒会报语法错误;
- 多字段排序:可指定多个字段排序(如 ORDER BY salary DESC, id ASC),表示“先按薪资降序,薪资相同时按id升序”;
- NULL值排序:若排序字段存在NULL值,NULL会被视为最小值,升序时排在最前面,降序时排在最后面;
- 效率优化:排序大表时,建议给排序字段建立索引,避免全表排序,提升查询效率。
MySQL多表查询
多表查询是DQL进阶核心操作,核心用于关联多个存在关联关系的表,联合获取所需数据(如关联员工表和部门表,查询员工所属部门完整信息),适配企业运维中复杂的数据查询场景。多表查询的详细用法可参考链接:MySQL多表查询