说明:DQL(Data Query Language,数据查询语言),用来查询数据库表中的记录。有的书中,会把DQL语言放入到DML(Data Manipulation Language,数据操作语言:数据的增删改)中,不单独拎出来。但既然有拎出来的,也侧面说明了查询语言的丰富。
查询分为:基本查询、条件查询、分组查询、排序查询、分页查询和多表查询,本文介绍前五个。
SQL语句的书写,要按照上述的顺序,不需要的可以跳过,但不能颠倒顺序;
准备工作:新建一张学生表(tb_stu),数据库中存入一些条目;
一、基本查询
(1)查询指定字段(姓名、年龄)的记录;
select name,age from tb_stu;
(2)查询所有字段的记录;
推荐使用方式二,方式二较为高效;
# 方式一
select * from tb_stu;
# 方式二
select id, username, password, name, age, gender, image, classify, join_date, create_date, last_modify_date from tb_stu;
(3)设置别名查询指定字段的记录;
在字段后面加as,表示该字段的别名是什么。as可以省略不写,直接在字段后面加别名
select name as '姓名', age as '年龄' from tb_stu;
# as可以省略
select name '姓名', age '年龄' from tb_stu;
(4)查询学生类比,并去除重复记录;
distinct 表示此次查询去重
select distinct classify from tb_stu;
(5)将学生的年龄+1显示;
select age + 1 from tb_stu;
二、条件查询
(1)查询指定姓名(加缪)的记录;
select * from tb_stu where name='加缪';
(2)查询限定条件(年龄大于18)的记录;
select * from tb_stu where age > 18;
(3)查询没有分配类型的记录;
需要注意,不要写成:where classify=null
select * from tb_stu where classify is null;
(4)查询有分配类型的记录;
同样,不要写成:where classify=not null 或者 where classify!=null
select * from tb_stu where classify is not null;
(5)查询密码不等于“123456”的记录;
select * from tb_stu where password!='123456';
郭靖的密码是’123456’,故没有查询出来
(6)查询入学日期在某个日期之间(2001-01-01~2023-01-01)的记录;
between 表示在什么之间
select * from tb_stu where join_date between '2001-01-01' and '2023-01-01';
(7)查询入学日期在某个日期之间(2001-01-01~2023-01-01),且性别为女的记录;
后面还有限定的话,可以在后面再加and
select * from tb_stu where join_date between '2001-01-01' and '2023-01-01' and gender='女';
(8)查询类型是1,2,3的记录;
in 表示取值是括号里面的,推荐使用这种方式,语句简洁明了
# 方式一
select * from tb_stu where classify in(1,2,3);
# 方式二
select * from tb_stu where classify=1 or classify=2 or classify=3;
(9)查询姓名为两个字的记录;
like 表示模糊查找,后面的内容包含通配符。通配符下划线(_)表示任意字符,(%)表示任意多个字符。想表示姓名为两个字,可以使用两个下划线(__)。
select * from tb_stu where name like '__';
(10)查询’李’姓学生的记录;
所以,如果要表示某记录字段包含某关键字,可以使用 ‘%关键字%’
select * from tb_stu where name like '李%'
三、分组查询
聚合函数,是MySQL中提供的用于计算的函数,有:count()、avg()、min()、max()、sum(),分别用于计算记录总数、平均值、最小值、最大值和总和。
(1)统计学生记录数量;
需要注意的是,count()不统计null
select count(*) from tb_stu;
(2)统计所有学生的年龄平均值;
select avg(age) from tb_stu;
(3)统计最早入学的学生日期;
select min(join_date) from tb_stu;
(4)统计最晚入学的学生日期;
select max(join_date) from tb_stu;
(5)统计所有的学生年龄之和;
select sum(age) from tb_stu;
(6)根据性别分组,统计男同学、女同学的数量;
group by 表示按字段分组
select gender,count(*) from tb_stu group by gender;
(7)查询入学时间在“2001-01-01~2023-06-03”之间的学生,并对结果根据类别分组,获取类别数量大于等于2的类别;
select classify '类别名',count(*) '数量' from tb_stu
where join_date between '2001-01-01' and '2023-06-03'
group by classify
having count(*) >= 2;
四、排序查询
(1)根据入学时间,对学生进行升序排序
order by 表示按照某字段排序,asc是升序(默认),desc是降序;
select * from tb_stu order by join_date asc;
# 不加asc,默认也是升序,所以需要升序的话,asc可以省略
select * from tb_stu order by join_date;
(2)根据入学时间,对学生进行降序排序;
select * from tb_stu order by join_date desc;
(3)根据入学时间,对学生升序排序,入学时间相同,再按照更新时间进行降序排序;
select * from tb_stu order by join_date asc, create_date desc;
五、分页查询
(1)从起始索引0开始,查询学生记录,每页展示5条记录;
limit 表示限定查询范围,只有一个数,表示从0开始;有两个数,表示从第一个数,限制到第一个数后面多少条;
select * from tb_stu limit 0, 5;
# 从0开始,0可以省略
select * from tb_stu limit 5;
(2)查询第2页学生信息,每页展示5条记录;
注意不要写成:limit 5,10,
select * from tb_stu limit 5, 5;
(3)查询第3页学生信息,每页展示5条记录;
值得注意的是,limit 10,5 超出数据库的范围,但不会报错;
select * from tb_stu limit 10, 5;
(4)分页查询
实际项目中的分页,肯定不会像上面这样,每次翻页都写一条新的SQL语句。而是用一个SQL语句,完成所有的翻页操作,只需要将SQL语句的内容改成下面这样:
select * from tb_stu limit (当前页码 - 1), 每页显示记录条数;
当前页码和每页显示记录条数,会有前端传参数进来
扩展
我们的数据库中存储的性别、类别类型是由数字代替的,访问数据传回到Service(业务逻辑层)时,会将数据处理,返给给前端时,将会恢复成(男、女)或(其他、小说家、作家、诗人)的具体类型名。在MySQL数据库中,也提供了对应的操作,可以在查询数据时,就将数据更改为对应的类型名。
(1)统计学生类别的数量(类似if三元表达式);
select if(gender=1, '男生','女生') name,count(*) vaule from tb_emp group by gender;
(此次查询并非来自上面创建的学生表中,因为学生表中的gender不是用数字表示的,无法展示)
(2)统计学生的类型数量(类似switch语句)
select case classify
when '0' then '其他'
when '1' then '小说家'
when '2' then '作家'
when '3' then '诗人'
else '未分配' end name,
count(*) value from tb_stu group by classify;
总结
(1)以上查询用到的关键字及作用如下:
(2)扩展中使用到的数据库提供的对数据进行转换的函数,不推荐使用。因为对请求的数据进行处理,这是三层架构的Service层中的任务,不应该放在数据库中操作。