一、dql 语言概述
dql(data query language,数据查询语言)是 sql 中用于从数据库查询数据的核心语言。官方文档:https://dev.mysql.com/doc/refman/8.4/en/select.html
二、完整执行顺序
理解 sql 的执行顺序是写出高效查询的关键。以下是 select 语句的完整执行顺序:
- from:确定数据源(哪张 / 哪些表)
- where:原始行过滤,分组之前筛选
- group by:对数据做分组
- having:分组之后对分组结果过滤,可以用聚合函数
- select:计算、选出要展示的字段,别名在这里才生成
- order by:对结果集排序
- limit:限制返回行数,做分页
三、关键字简单释义
| 关键字 | 作用 |
|---|---|
| distinct | 去重 |
| where | 行级过滤,不能写聚合函数 |
| group by | 分组,配合聚合函数(count / sum / avg) |
| having | 分组后过滤,可以使用聚合函数 |
| order by | 排序,asc 升序,desc 降序 |
| limit offset, count | 分页,offset 偏移量,count 取多少行 |
| for update / share | 行锁,用于事务并发 |
四、基础查询
4.1 语法格式
-- select 查询列表(2) -- from 表名(1); -- 注意:select 标识选择哪些列;from 标识从哪个表中选择。 -- 查询列表可以是:表中的字段、常量值、表达式、函数
4.2 查询字段
-- 查询 employees 表中多个字段 select last_name from employees; -- 查询 employees 表中多个字段 select employee_id, first_name, last_name from employees;
4.3 查询所有字段
-- 方式一:
select * from employees;
-- 方式二:
select
-- 所有字段名
from employees;4.4 查询常量值、表达式和函数
-- 查询常量值 select 66; select 'bigdata'; -- 查询表达式 select 100 * 2; -- 查询函数(版本) select version();
4.5 取别名
取别名的关键字是 as。取别名的好处:便于理解;便于区分。
-- 使用 as select 100 * 2 as 结果; -- 使用空格 select 100 * 2 结果; select salary as 'out put' from employees;
4.6 去重 distinct
-- 查询员工表中涉及到的所有部门编号 -- 没有去重 select department_id from employees; -- 去重之后 select distinct department_id from employees;
4.7 + 号的作用
mysql 中 + 号只有一个功能:运算符。注意以下三种情况:
- 两个操作数都为数值型,则做加法运算:
select 66 + 99; - 只要其中有一方为字符型,试图将字符型转化为数值型:
select 66 + '99';如果转换成功,则继续做加法运算;如果转换失败,则将字符型转化为 0 再做运算:select 66 + "中"; - 只要其中一方为 null,结果一定为 null:
select null + 70;
4.8 concat() 函数
-- 查询员工名和姓,连成一个字段,并显示为姓名
select last_name + first_name as 姓名 from employees;
-- concat() 函数
select concat('h','e','l','l','o') as out_put;
-- 查询结果:out_put 列输出 hello
select concat(last_name, first_name) as 姓名 from employees;
-- 查询结果:把 last_name(姓)和 first_name(名)拼接成一个字段,列别名叫做姓名,输出每一条员工的拼接后的完整姓名五、条件查询
5.1 语法格式
-- select 查询列表(3) -- from 表名(1) -- where 筛选条件(2);
5.2 筛选条件分类
- 按条件表达式筛选:简单条件运算符:>、<、>=、<=、!=(<>)
- 按逻辑表达式筛选:&&(and)、||(or)、!(not)
- &&(and):两个条件都为 true,结果为 true,反之为 false
- ||(or):只要有一个条件为 true,结果为 true,反之为 false
- !(not):如果连接的条件本身为 false,结果为 true,反之为 false
- 模糊查询:like、between ... and ...、in()、is、is not、is not null、is null
5.3 按条件表达式筛选
-- 查询工资大于 12000 的员工信息 select * from employees where salary > 12000; -- 查询部门编号不等于 90 号的员工名和部门编号 select first_name, department_id from employees where department_id != 90;
5.4 按逻辑表达式筛选
-- 查询工资在 10000 到 20000 之间的员工名、工资以及奖金率 select first_name, salary, commission_pct from employees where salary >= 10000 and salary <= 20000; -- 查询部门编号不是在 90 到 110 之间,或者工资高于 15000 的员工信息 select * from employees where not(department_id < 90 and department_id > 110) or salary > 15000;
5.5 模糊查询
5.5.1 like
like 一般和通配符搭配使用。通配符说明:
- %:任意多个字符,包含 0 个字符
- _:任意单个字符
-- 查询员工名中包含字符 a 的员工信息 select * from employees where first_name like '%a%'; -- 查询员工名中第三个字符为 e,第五个字符为 a 的员工 select first_name, salary from employees where first_name like '__e_a%'; -- 查询员工姓中第二个字符为 _ 的员工名 -- 知识点:_ 是通配符,想要匹配普通下划线字符,需要用反斜杠 \ 转义 \_ select last_name from employees where last_name like '_\_%'; -- escape 指定自定义转义字符 -- last_name like '_$_%' escape '$'
5.5.2 between ... and ...
包含两个临界值,两个临界值不要调换顺序,提高语法的简洁度。
-- 查询员工编号在 100 到 120 之间的员工信息 select * from employees where employee_id between 100 and 120;
5.5.3 in()
判断某个字段的值是否属于 in 列表中的某一项,in 列表的值类型必须一致或兼容,提高语法的简洁度。
-- 查询员工的工种编号是 it_prog、ad_vp、ad_pres 中的一个员工名和工种编号 select first_name, job_id from employees where job_id = 'it_prog' or job_id = 'ad_vp' or job_id = 'ad_pres';
5.5.4 is null / is not null
is null 或者 is not null 判断空值。注意:= 或 <>(!=)不能判断 null 值。
-- 查询没有奖金率的员工名和奖金率 select first_name, commission_pct from employees where commission_pct is not null;
5.5.5 安全等于 <=>
安全等于 <=> 既可以判断普通数值相等,也可以判断 null 值相等。
-- 查询没有奖金率的员工和奖金率 select first_name, commission_pct from employees where commission_pct <=> null;
注意:salary is 12000 不可以运行,is 不等于等于号。
六、排序查询
排序查询用于对查询结果集按指定字段进行排序,是日常开发中使用频率极高的操作。以下是排序查询的完整语法格式:
-- select 查询列表(3)
-- from 表(1)
-- 【where 筛选条件】(2)
-- 【group by 分组】
-- 【having 分组后筛选】
-- order by {列名 | 表达式 | 位置} 【asc | desc】(4)
-- 【limit 分页】;排序查询的语法要点如下:
- asc:代表升序;desc:代表降序,如果不写,默认升序。
- order by 子句中可以支持单个字段、多个字段、表达式、函数、别名。
- order by 子句一般是放在查询语句的最后面,但是 limit 子句除外。
6.1 按单个字段排序
查询员工信息,要求工资从高到低排序。
-- 分析: -- 查询的表:employees -- 查询的字段:* -- 查询的条件:无 -- 排序条件:salary desc select * from employees order by salary desc;
6.2 添加筛选条件后排序
查询部门编号大于等于 90 的员工信息,按入职时间的先后顺序进行排序。
-- 分析: -- 查询的表:employees -- 查询的字段:* -- 查询的条件:department_id >= 90 -- 排序条件:hiredate desc select * from employees where department_id >= 90 order by hiredate desc;
6.3 按表达式排序
按年薪的高低显示员工的信息和年薪。年薪 = salary * 12 * (1 + commission_pct)。
-- 分析:
-- 查询的表:employees
-- 查询的字段:* 年薪
-- 查询的条件:无
-- 排序条件:salary * 12 * (1 + commission_pct) desc
-- ifnull(commission_pct,0):判断是否为空,如果为空补 0
select *,
salary * 12 * (1 + ifnull(commission_pct,0)) as 年薪
from employees
order by salary * 12 * (1 + ifnull(commission_pct,0)) desc;6.4 按别名排序
按年薪的高低显示员工的信息和年薪,直接使用别名作为排序条件。
select *,
salary * 12 * (1 + ifnull(commission_pct,0)) as 年薪
from employees
order by 年薪 desc;6.5 按函数排序
按姓名的长度显示员工的姓名和工资。
-- 分析:
-- 查询的表:employees
-- 查询的字段:姓名 长度 工资
-- 查询的条件:无
-- 排序条件:函数排序 desc
select length(concat(last_name, first_name)) as 姓名长度,
concat(last_name, first_name) as 姓名,
salary
from employees
order by 姓名长度 desc;知识点说明:
- concat():拼接字符串,把姓和名拼成全名。
- length():获取拼接后字符串的字节长度。
- order by 直接使用函数表达式做排序条件,降序 desc。
6.6 按多个字段排序
查询员工信息,要求先按工资升序,再按员工编号降序。
-- 分析: -- 查询的表:employees -- 查询的字段:* -- 查询的条件:无 -- 排序条件:salary asc employee_id desc select * from employees order by salary asc, employee_id desc;
知识点说明:
- 多字段排序用逗号分隔,优先级从左到右。
- 先按第一个字段排序,只有第一个字段值相等时,才会使用第二个字段排序。
- asc 升序(默认可以省略),desc 降序,每个字段都可以单独指定排序方式。
七、常见函数
函数:将一组逻辑语句封装在方法中,对外暴露方法名,类比于 python 中的方法。函数的好处:隐藏了细节;提高代码的重用性。
函数调用语法格式:
select 函数名(实参列表) [from 表名];
函数特点:叫什么(函数名称);干什么(函数功能)。函数的分类:单行函数、分组函数。单行函数包括:字符函数、数值函数、日期函数、其他函数、流程控制函数(if、case 结构)等。
7.1 字符函数
7.1.1 length()
length(str):获取参数值的字节个数。注意:对于非 ascii 字符(如汉字),length 函数返回的不是字符的个数,而是字符串的字节数。
select length('hello');
select length('你好hello');
-- 查看 mysql 默认编码格式
show variables like '%char%';7.1.2 concat()
concat():返回连接后的字符串。
select concat(last_name, first_name) from employees;
select concat('2026', '-', '08', '-', '17');7.1.3 concat_ws()
concat_ws():返回带分隔符的连接结果。concat_ws 会自动跳过 null 值,不会把 null 带入拼接结果。
select concat_ws('-', '2026', '08', '17');7.1.4 upper() 和 lower()
upper(str):返回根据当前字符集映射将所有字符转换为大写的字符串;lower(str):返回根据当前字符集映射将所有字符转换为小写的字符串。
select upper('hello');
select lower('hello');
-- 将姓变为大写,名变为小写,然后拼接
select concat(upper(last_name), lower(first_name)) as name_concat
from employees;
select concat_ws('_', upper(last_name), lower(first_name)) as name_concat
from employees;7.1.5 substr() / substring()
substr(str, pos) 和 substring(str, pos):返回指定的子字符串。str 是原始字符串,pos 是子字符串的起始位置,从 1 开始。substr 和 substring 在 mysql 里完全等价,可以互换使用。mysql 字符串下标从 1 开始,不是 0。
select substr('abcdef', 2); -- bcdef,从第 2 位截取到末尾
select substr('abcdef', 2, 3); -- bcd,从第 2 位截取 3 个字符
-- 姓名中的姓首字母大写,其他字符小写,然后使用 _ 拼接,显示为 out_put
select concat(upper(substr(last_name, 1, 1)), '_', lower(substr(last_name, 2))) out_put
from employees;7.1.6 instr()
instr():返回子字符串首次出现的索引。如果子字符串不在原始字符串中,则返回 0,函数不区分大小写。
-- 查找 'hello' 里面 'el' 的位置
select instr('hello', 'el'); -- 结果:2
-- 子串不存在,返回 0
select instr('hello', 'xx'); -- 结果:0
-- 表中使用:查找 last_name 中包含 'in' 的位置
select last_name, instr(last_name, 'in') pos from employees;7.1.7 trim() / rtrim() / ltrim()
trim():删除前导空格和尾随空格;rtrim():删除尾随空格;ltrim():删除前导空格。
-- 去掉前后空格
select trim(' abc '); -- abc
-- 只去掉右边(尾部)空格
select rtrim(' abc '); -- ' abc'
-- 只去掉左边(头部)空格
select ltrim(' abc '); -- 'abc '7.1.8 lpad() / rpad()
lpad(str, len, padstr):返回字符串参数,并在左侧填充指定的字符串;rpad(str, len, padstr):返回字符串参数,并在右侧填充指定的字符串。
-- 原字符串 'abc',总长度 5,左边用 * 填充
select lpad('abc', 5, '*'); -- 结果:**abc
-- 原字符串长于总长度,截断右边
select lpad('abcdef', 4, '*'); -- 结果:abcd
select rpad('abc', 5, '*'); -- 结果:abc**
-- 思考:马冬梅 ——> 马 * 梅
select concat(rpad(substring('马冬梅', 1, 1), 2, '*'), substring('马冬梅', 3, 1)) as res;
-- 输出结果:马*梅7.1.9 replace()
replace(str, from_str, to_str):替换指定字符串的所有出现位置。参数含义:replace(原字符串, 要被替换的内容, 替换成的内容)。
-- 把字符串中的 a 全部换成 *
select replace('abcab', 'a', '*'); -- 结果:*bc*b
-- 删除中间空格(把空格替换为空)
select replace('a b c', ' ', ''); -- 结果:abc7.2 数学函数
7.2.1 round()
round(x, d):将参数 x 四舍五入到 d 位小数。
select round(3.14); -- 结果 3 select round(3.56); -- 结果 4 select round(3.1415, 2); -- 保留 2 位小数,结果 3.14
7.2.2 ceil()
ceil():返回不小于某个值的最小整数值 x,即向上取整。
select ceil(3.1415926); -- 4 select ceil(3.0); -- 3 select ceil(-2.3); -- -2
7.2.3 floor()
floor(x):返回不大于某个特定值的最大整数值 x,即向下取整,返回小于或等于该数值的最大整数。
select floor(3.999); -- 3 select floor(3.0); -- 3 select floor(-2.3); -- -3
7.2.4 truncate()
truncate(x, d):用于将数值截断到指定的小数位数,直接去掉多余的小数位而不进行四舍五入。
select truncate(123, d); select truncate(3.999, 1); -- 3.9 select truncate(3.1415, 2); -- 3.14 select truncate(3.999, 0); -- 3
7.2.5 mod()
mod(n, m):n % m 或 n mod m,用于计算两个数之间的余数(模运算)。n 为被除数,m 为除数。
select mod(10, 3); -- 1 select 10 % 3; -- 1 select 10 mod 3; -- 1
7.3 日期函数
7.3.1 now()
now():返回当前日期和时间的值,格式为 yyyy-mm-dd hh:mm:ss。
select now(); -- 2026-08-17 17:12:49
7.3.2 curdate()
curdate():返回当前日期。
select curdate(); -- 2026-08-17
7.3.3 curtime()
curtime():返回当前时间,格式为 hh:mm:ss。
select curtime(); -- 17:14:34
7.3.4 year()
year():返回年份。
select year(now());
select year('2026-08-17');
-- 查看员工表中入职时间的年份信息
select year(hiredate) from employees;7.3.5 month()
month():返回月份。
select month(now());
7.3.6 monthname()
monthname():返回月份名称。
select monthname(now());
7.3.7 day()
day():返回日。
select day(now());
7.3.8 hour()
hour():提取小时。
select hour(now());
7.3.9 minute()
minute():从参数中返回分钟数。
select minute(now());
7.3.10 second()
second():返回秒。
select second(now());
7.3.11 str_to_date()
str_to_date(str, format):将字符串转换为日期。str 为要转换的日期和时间字符串,format 为指定字符串的格式。
格式化符号说明:
- %y:四位数字的年份。
- %y:两位数字的年份。
- %m:两位数字的月份(01 到 12)。
- %c:月份,数值(0 到 12)。
- %d:两位数字的日期(00 到 31)。
- %e:日期,数值(0 到 31)。
- %h:两位数字的小时,24 小时制(00 到 23)。
- %h:两位数字的小时,12 小时制(01 到 12)。
- %i:两位数字的分钟(00 到 59)。
- %s:两位数字的秒(00 到 59)。
- %p:am 或 pm。
select str_to_date('2026-08-17', '%y-%m-%d') as out_put;
-- 查询入职日期为 1992-04-03 的员工信息
select *
from employees
where hiredate = '1992-04-03';
select *
from employees
where hiredate = str_to_date('4-3 1992', '%c-%d %y');7.3.12 date_format()
date_format(date, format):将日期或日期时间值格式化为指定的字符串格式。date 为要格式化的日期或日期时间,format 为指定结果字符串的格式。
格式化符号说明:
- %y:四位数字的年份。
- %y:两位数字的年份。
- %m:月份名称(january 到 december)。
- %m:两位数字的月份(01 到 12)。
- %c:月份,数值(1 到 12)。
- %d:带有英文序数后缀的月份中的天(1st, 2nd, 3rd, ...)。
- %d:两位数字的日期(00 到 31)。
- %e:日期,数值(0 到 31)。
- %h:两位数字的小时,24 小时制(00 到 23)。
- %h:两位数字的小时,12 小时制(01 到 12)。
- %i:两位数字的分钟(00 到 59)。
- %s:两位数字的秒(00 到 59)。
- %p:am 或 pm。
- %w:星期名称(sunday 到 saturday)。
- %w:星期中的天(0 = sunday,6 = saturday)。
- %j:一年中的天数(001 到 366)。
select date_format(now(), '%y年%m月%d日');
-- 查询有奖金率的员工名和入职日期(xx月/xx日 xx年)
select first_name,
date_format(hiredate, '%m月/%d日 %y年')
from employees
where commission_pct is not null;7.4 其他函数
7.4.1 version()
version():返回一个字符串,指示 mysql 服务器版本。
select version();
7.4.2 user()
user():返回客户端提供的用户名和主机名。
select user();
到此这篇关于mysql dql 查询语言详解:从基础查询到条件筛选的文章就介绍到这了,更多相关mysql dql 查询语言内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论