本篇目录
1.数据操作-增删改查(基本)
- 01.简单查询
- 02.添加数据
- 03.修改
- 04.删除
2.数据操作-简单查询
- 01.查询(所有字段,指定字段、as)
- 02.消除重复行
3.条件
- 01.比较运算
- 02.逻辑运算
- 03.模糊查询
- 04.范围查询
- 05.空判断
4.排序
5.聚合函数
6.分组
7.获取部分行
8.分页
9.连接查询
- 01.等值连接查询
- 02.左连接查询
- 03.右连接查询
重点:各种查询一定要会。这篇基本都是重点。
1.数据操作-增删改查(基本)
01.简单查询
select * from 表名
例:查询所有学生数据
select * from students
02.添加数据
添加一行数据
- 格式一:所有字段设置值,值的顺序与表中字段的顺序对应
- 说明:主键列是自动增长,插入时需要占位,通常使用0或者 default 或者 null 来占位,插入 成功后以实际数据为准
insert into 表名 values(...)
例:插入一个学生,设置所有字段的信息
insert into students values(0,'亚瑟',22,177.56)
- 格式二:部分字段设置值,值的顺序与给出的字段顺序对应
insert into 表名(字段1,...) values(值1,....)
例:插入一个学生,只设置姓名
insert into students(name) values('老夫子')
添加多行数据
方式一:写多条insert语句,语句之间用英文分号隔开
insert into students(name) values('老夫子2'); insert into students(name) values('老夫子3');
方式二:写一条insert语句,设置多条数据,数据之间用英文逗号隔开(比方式一更好)
格式一:insert into 表名 values(...),(...)...
例:插入多个学生,设置所有字段的信息
insert into students values(0,'亚瑟3',23,167.56),(0,'亚瑟4',23,167.56)
格式二:insert into 表名(列1,...) values(值1,...),(值1,...)...
例:插入多个学生,只设置姓名
insert into students(name) values('老夫子5'),('老夫子6')
03.修改
可以修改多个字段。
格式:update 表名 set 列1=值1,列2=值2... where 条件
例:修改id为5的学生数据,姓名改为 狄仁杰,年龄改为 20
update students set name='狄仁杰',age=20 where id=5
04.删除:delete from
delete from table 删除是删除数据,表还存在
drop table 是删除表的,数据肯定也不在了
格式:delete from 表名 where 条件
例:删除id为6的学生数据
delete from students where id=6
逻辑删除:对于重要的数据,不能轻易执行delete语句进行删除,一旦删除,数据无法恢复,这 时可以进行逻辑删除
- 1、给表添加字段,代表数据是否删除,一般起名isdelete,0代表未删除,1代表删除,默认值为0
- 2、当要删除某条数据时,只需要设置这条数据的isdelete字段为1
- 3、以后在查询数据时,只查询出isdelete为0的数据
1、给学生表添加字段(isdelete),默认值为0,如果表中已经有数据,需要把所有数据的isdelete字段更新为0。
alter table students add isdelete int default 0;
下面的好像不行
update students set isdelete=0;
2、删除id为1的学生
update students set isdelete=1 where id=1
3、查询未删除的数据
select * from students where isdelete=0
2.数据操作-简单查询
首先要创建表,准备数据。
创建数据表
drop table if exists students; create table students ( studentNo varchar(10) primary key, name varchar(10), sex varchar(1), hometown varchar(20), age tinyint(4), class varchar(10), card varchar(20) )
准备数据
insert into students values ('001', '王昭君', '女', '北京', '20', '1班', '340322199001247654'), ('002', '诸葛亮', '男', '上海', '18', '2班', '340322199002242354'), ('003', '张飞', '男', '南京', '24', '3班', '340322199003247654'), ('004', '白起', '男', '安徽', '22', '4班', '340322199005247654'), ('005', '大乔', '女', '天津', '19', '3班', '340322199004247654'), ('006', '孙尚香', '女', '河北', '18', '1班', '340322199006247654'), ('007', '百里玄策', '男', '山西', '20', '2班', '340322199007247654'), ('008', '小乔', '女', '河南', '15', '3班', null), ('009', '百里守约', '男', '湖南', '21', '1班', ''), ('010', '妲己', '女', '广东', '26', '2班', '340322199607247654'), ('011', '李白', '男', '北京', '30', '4班', '340322199005267754'), ('012', '孙膑', '男', '新疆', '26', '3班', '340322199000297655')
01.查询(所有字段,指定字段、as)
所有字段:*
select * from 表名
例:select * from students
查询指定字段:
方式一:字段名
select 列1,列2,... from 表名
例:如果是单表查询 可以省略表明
select name,age from students
方式二:表名.字段名(多表)
select students.name,students.age from students
可以通过 as 给表起别名
select s.name,s.age from students as s
使用as给字段起别名
select studentNo as 学号,name as 名字,sex as 性别 from students
02.消除重复行
在select后面列前使用distinct可以消除重复的行
select distinct 列1,... from 表名;
例:select distinct sex from students;
3.条件
使用where子句对表中的数据筛选,符号条件的数据会出现在结果集中 语法如下:
select 字段1,字段2... from 表名 where 条件;
例:select name from students where id=1;
注:字段name:想显示的字段,条件id:筛选的行
where后面支持多种运算符,进行条件的处理
- 比较运算
- 逻辑运算
- 模糊查询
- 范围查询
- 空判断
01.比较运算符
- 等于: =
- 大于: >
- 大于等于: >=
- 小于: <
- 小于等于: <=
- 不等于: != 或 <>
等于: =
例1:查询小乔的年龄
select age from students where name='小乔'
小于: <
例2:查询20岁以下的学生
select * from students where age<20
不等于: != 或 <>
例3:查询家乡不在北京的学生
select * from students where hometown!='北京'
练习:
1、查询学号是'007'的学生的身份证号
select card from students where studentNo='007';
2、查询'1班'以外的学生信息
select * from students where class != '1班'
3、查询年龄大于20的学生的姓名和性别
select name,sex from students where age > 20;
02.逻辑运算符
- and:与
- or:或
- not:非
and:与关系
例1:查询年龄小于20的女同学
select * from students where age<20 and sex='女'
or:或关系
例2:查询女学生或'1班'的学生
select * from students where sex='女' or class='1班'
not:非关系
例3:查询非天津的学生
select * from students where not hometown='天津'
练习:
1、查询河南或河北的学生
select * from students where hometown='河南' or hometown='河北';
2、查询'1班'的'上海'的学生
select * from students where class='1班' and hometown='河北';
3、查询非20岁的学生
select * from students where not age='20'
03.模糊查询:like 、%、_
- like
- %表示任意多个任意字符
- _表示一个任意字符
like:模糊查询关键字
例1:查询姓孙的学生
select * from students where name like '孙%'
_:表示一个任意字符
例2:查询姓孙且名字是一个字的学生
select * from students where name like '孙_'
%表示:任意多个任意字符
例3:查询叫乔的学生
select * from students where name like '%乔'
例4:查询姓名含白的学生
select * from students where name like '%白%'
练习:
1、查询姓名为两个字的学生
select * from students where name like '__'
2、查询姓百且年龄大于20的学生
select * from students where age>20 and name like '百%'
3、查询学号以1结尾的学生
select * from students where studentNo like '%1'
04.范围查询:in、between ... and ...
in:表示在一个非连续的范围内
例1:查询家乡是北京或上海或广东的学生
select * from students where hometown in('北京','上海','广东')
between ... and ...:表示在一个连续的范围内
例2:查询年龄为18至20的学生
select * from students where age between 18 and 20
between 18 and 20 : 包含18和20
练习:
1、查询年龄在18或19或22的女生
select * from students where age in(18,19,22) and sex='女'
2、查询年龄在20到25以外的学生
select * from students where age between 20 and 25
05.空判断(判空:is null 判非空:is not null)
判空:is null (不能写成=null,是错的)
例1:查询没有填写身份证的学生
select * from students where card is null
区分:null和空字符串
红箭头指的就是:null 蓝箭头指的就是空字符串
使用navicat造成null:不写东西
使用navicat造成空字符串:写了又删了
sql语句插入:
insert into ....values(null)
insert into ....values('')
判非空is not null
例2:查询填写了身份证的学生
select * from students where card is not null
4.排序
排序:order by
为了方便查看数据,可以对数据进行排序
语法:
select * from 表名 order by 列1 asc|desc,列2 asc|desc,...
- 将行数据按照列1进行排序,如果某些行列1的值相同时,则按照列2排序,以此类推
- 默认按照列值从小到大排列
- asc从小到大排列,即升序(不写,默认升序)
- desc从大到小排序,即降序
例1:查询所有学生信息,按年龄从小到大排序
select * from students order by age
例2:查询所有学生信息,按年龄从大到小排序,年龄相同时,再按学号从小到大排序
select * from students order by age desc,studentNo
age:降序,studentNo:没写,默认升序。注意:每个都要单独写降序还是升序
练习:
1、查询所有学生信息,按班级从小到大排序,班级相同时,再按学号再按学号从小到大排序
select max(age) as '最大年龄',min(age) as '最小年龄',avg(age) as '平均年龄' from students
2.中文名字排序
select * from students ORDER BY convert(name using gbk)
5.聚合函数
- 为了快速得到统计数据,经常会用到如下5个聚合函数
- count(*)表示计算总行数,括号中写星与列名,结果是相同的 (count用的比较多)
- 聚合函数不能在 where 中使用
count(*):表示计算总行数,括号中写星与列名,结果是相同的
- count(*):*表示,这一行任意一列有值,都统计在内。(一般count(*)比较多)
- count(字段):有null值就不统计。
例1:查询学生总数
select count(*) from students;
max(列)表示求此列的最大值
例2:查询女生的最大年龄
select max(age) from students where sex='女';
min(列)表示求此列的最小值
例3:查询1班的最小年龄
select min(age) from students;
sum(列)表示求此列的和
例4:查询北京学生的年龄总和
select sum(age) from students where hometown='北京';
avg(列)表示求此列的平均值
例5:查询女生的平均年龄
select avg(age) from students where sex='女'
练习
1、查询所有学生的最大年龄、最小年龄、平均年龄
select max(age) as '最大年龄',min(age) as '最小年龄',avg(age) as '平均年龄' from students
2、一班共有多少个学生
select count(*) from students where class='1班'
3、查询3班年龄小于18岁的同学有几个
select count(*) from students where class='3班' and age < 18
6.分组
按照字段分组,表示此字段相同的数据会被放到一个组中 分组后,分组的依据列会显示在结果集中,其他列不会显示在结果集中,可以做到去重, 可以对分组后的数据进行统计,做聚合运算语法:
select 列1,列2,聚合... from 表名 group by 列1,列2...
例1:查询各种性别的人数
select sex,count(*) from students group by sex
例2:查询各种年龄的人数
select age,count(*) from students group by age
例3:按性别分组,每组只显示一行数据,(所以上面,基本结合聚合运算)
select * from students GROUP BY sex;
例4:按年龄+性别 分组
select class,sex,count(*) from students GROUP BY class,sex;
练习
查询各个班级学生的平均年龄、最大年龄、最小年龄
select class,avg(age) as '平均年龄',max(age) as '最大年龄',min(age) as '最小年龄' from students group by class
分组后的数据筛选,语法:
select 列1,列2,聚合... from 表名 group by 列1,列2,列3... having 列1,...聚合..
having必须在group by后面使用(不能在它前面使用),也不能单独使用
having后面的条件运算符与where的相同
例1:查询男生总人数
方案一
select count(*) from students where sex='男'
方案二:
select sex,count(*) from students group by sex having sex='男'
练习
查询1班除外其他班级学生的平均年龄、最大年龄、最小年龄
select class,avg(age) as '平均年龄',max(age) as '最大年龄',min(age) as '最小年龄' from students group by class HAVING class !='1班'
对比where与having
where是对from后面指定的表进行数据筛选,属于对原始数据的筛选
having是对group by的结果进行筛选
7.获取部分行
当数据量过大时,在一页中查看数据是一件非常麻烦的事情
语法
select * from 表名 limit start,count
从start开始,获取count条数据
start索引从0开始
例1:查询前3行学生信息,这是按数据加入时数据的排序
select * from students limit 0,3
例2:查询前3行学生信息,这是按年龄升序的排序
select * from students order by age limit 0,3
练习
查询第4到第6行学生信息
select * from students limit 3,3
8.分页
已知:每页显示m条数据,求:显示第n页的数据
select * from students limit (n-1)*m,m
求总页数
- 查询总条数p1
- 使用p1除以m得到p2
- 如果整除则p2为总数页
- 如果不整除则p2+1为总页数
练习:
每页显示5条数据,显示每一页的数据
第一页: select * from students limit 0,5
第二页: select * from students limit 5,5
第三页: select * from students limit 10,5
9.连接查询
连接查询:等值查询、左连接查询、右连接查询
- 当查询结果的列来源于多张表时,需要将多张表连接成一个大的数据集,再选择合适的列返回
- 等值连接查询:查询的结果为两个表匹配到的数据
- 左连接查询:左表的记录将会全部表示出来,而右表(b_table)只会显示符合搜索条件的记录。右表记录不足的地方均为NULL
- 右连接查询:左表只会显示符合搜索条件的记录,而右表的记录将会全部表示出来。左表记录不足的地方均为NULL。
准备数据
drop table if exists courses; create table courses ( courseNo int(10) unsigned primary key auto_increment, name varchar(10) );
insert into courses values ('1', '数据库'), ('2', 'qtp'), ('3', 'linux'), ('4', '系统测试'), ('5', '单元测试'), ('6', '测试过程');
drop table if exists scores;
create table scores ( id int(10) unsigned primary key auto_increment, courseNo int(10), studentno varchar(10), score tinyint(4) );
insert into scores values ('1', '1', '001', '90'), ('2', '1', '002', '75'), ('3', '2', '002', '98'), ('4', '3', '001', '86'), ('5', '3', '003', '80'), ('6', '4', '004', '79'), ('7', '5', '005', '96'), ('8', '6', '006', '80');
01.等值连接
方式一(不好,生成的记录=表1的总数*表2的总数会产生临时表,造成笛卡尔积)
select * from 表1,表2 where 表1.列=表2.列
方式二(又称内连接),更优先选这个。
select * from 表1 inner join 表2 on 表1.列=表2.列
方式一:先连接,再筛选
方式二:先筛选,再连接
例1:查询学生信息及学生的成绩
select * from students as stu inner join scores as sc on stu.studentNo = sc.studentNo
下面是三张表students学生表,courses课程表,和scores成绩表。
先把students学生表的第一条数据拿出来,学号为studentNo=001,对着scores成绩表,看是否有对应学号有studentNo=001,有的话,就把这条数据放在后面。组成一条数据。
一直这样,把students学生表studentNo=009时拿出来,对应着scores成绩表,是没有studentsNo=009的成绩数据,所以students学生表的studentNo=009这条数据就不要,scores成绩表没有也不要这条数据了。
如果是scores成绩表有studentNo=100,students学生表没有studentNo=100,那scores成绩表的studentNo=100这条数据不要,students学生表没有也不要这条数据。
![](https://img2020.cnblogs.com/blog/1277786/202106/1277786-20210601171906256-382560854.png)
数据库和excel现实的数据不一样没有关系。excel只是便于理解。
students表
courses表和scores表
查询到的结果:students表,studentNo=1-12,scores表,studentNo=1,6。查询的结果就是studentNo=1,6。取两张表都有的数据。
例2:查询课程信息及课程的成绩
select
*
from
courses as cs
inner join scores as sc on cs.courseNo = sc.courseNo;
查询到的结果:courses表 coursesNo=1-8 scores表 coursesNo=1,6。 内连接查询结果就是1-6,两张表都有的数据。
例3:查询学生信息及学生的课程对应的成绩
select * from students as stu inner join scores as sc on stu.studentNo = sc.studentNo inner join courses as cs on cs.courseNo = sc.courseNo;
例4:查询王昭君的成绩,要求显示姓名、课程号、成绩
select stu.name, sc.courseNo, sc.score from students as stu inner join scores as sc on stu.studentNo = sc.studentNo where stu.name = '王昭君';
例5:查询王昭君的数据库成绩,要求显示姓名、课程名、成绩
三张表连接的时候,其中一张表和另外两个都有连接,并不一定要放在第一个。放在第二个也可以,只要在用到的前面定义就行。
select stu.name, cs.name, sc.score from students as stu inner join scores as sc on stu.studentNo = sc.studentNo inner join courses as cs on sc.courseNo = cs.courseNo where stu.name = '王昭君' and cs.name = '数据库';
例6:查询所有学生的数据库成绩,要求显示姓名、课程名、成绩
select stu.name, cs.name, sc.score from students as stu inner join scores as sc on stu.studentNo = sc.studentNo inner join courses as cs on sc.courseNo = cs.courseNo where cs.name = '数据库';
例7:查询男生中最高成绩,要求显示姓名、课程名、成绩
select stu.name, cs.name, sc.score from students as stu inner join scores as sc on stu.studentNo = sc.studentNo inner join courses as cs on sc.courseNo = cs.courseNo where stu.sex = '男' order by sc.score desc limit 1;
02.左连接:left join on
select * from 表1 left join 表2 on 表1.列=表2.列
例1:查询所有学生的成绩,包括没有成绩的学生
select * from students as stu left join scores as sc on stu.studentNo = sc.studentNo;
右边没有的就显示为null
查询的结果为:
例2:查询所有学生的成绩,包括没有成绩的学生,需要显示课程名
select * from students as stu left join scores as sc on stu.studentNo = sc.studentNo left join courses as cs on cs.courseNo = sc.courseNo;
03.右连接:right join on
select * from 表1 right join 表2 on 表1.列=表2.列
添加两门课程
insert into courses values (0, '语文'), (0, '数学');
例1:查询所有课程的成绩,包括没有成绩的课程
select * from scores as sc right join courses as cs on cs.courseNo = sc.courseNo;
例2:查询所有课程的成绩,包括没有成绩的课程,包括学生信息
select * from scores as sc right join courses as cs on cs.courseNo = sc.courseNo left join students as stu on stu.studentNo = sc.studentNo;
先scores成绩表和courses课程表右连接,左边的scores没有的null。这个连接的新表为左边的表,再和students学生表进行左连接,学生表没有的补充null值。