基于mysql8.0.19-数据操作(增删查改,分组聚合,过滤,查询顺序,限制查询记录)
mysql-配置文件设置
[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8
[mysqld]
# 设置3306端口
port = 3306
# 设置mysql的安装目录
basedir = D:\\mysql-8.0.19-winx64\\
# 设置mysql数据库的数据的存放目录
datadir =D:\\mysql-8.0.19-winx64\\data
# 允许最大连接数
max_connections=200
# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
# 创建模式
sql_mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
数据的增删改和select操作
create database day39;
create table t1(
id int primary key auto_increment, 主键(不能为空不能重复) 自增
username char(12) not null,
sex enum(‘male’,‘female’) default ‘male’, 单选(枚举) 默认
hobby set(‘上课’,‘写作业’,‘考试’) not null 多选
);
增加数据
1.insert into 表 values(值);
insert into t1 values(1,'大壮','male','上课,写作业');
insert into t1 values(2,'杜相玺','male','上课,写作业');
insert into t1 values(3,'b哥','male','写作业'),(4,'庄博','male','考试');
2.指定字段插入数据
语法:
insert into 表名(字段1,字段2,字段3…) values (值1,值2,值3…);
insert into t1(username,hobby) values('杨得港','上课,写作业,考试'),('李帅','考试');
select * from t1;
3.插入多条记录
语法:
insert into 表名 values (值1,值2,值3…值n), (值1,值2,值3…值n), (值1,值2,值3…值n);
4.插入查询结果
语法:
insert into 表名(字段1,字段2,字段3…字段n) select 字段1,字段2,字段3…字段n from 表2;
create table t2(id int,name char(12));
insert into t2(id,name) select id,username from t1;
删除数据
清空表:
delete from 表;
**delete from 表名; #如果有自增id,新增的数据,仍然是以删除前的最后一样作为起始。**
**truncate table 表名;数据量大,删除速度比上一条快,且直接从零开始,**
删除某一条数据
语法:
delete from t2---------------删除t2整张表
delete from t1 where id = 3;
id | username | sex | hobby |
±—±----------±-----±------------------------+
| 1 | 大壮 | male | 上课,写作业 |
| 2 | 杜相玺 | male | 上课,写作业 |
| 4 | 庄博 | male | 考试 |
| 5 | 杨得港 | male | 上课,写作业,考试 |
| 6 | 李帅 | male | 考试
delete from t1;
insert into t1(username,hobby) values('杨得港','上课,写作业,考试'),('李帅','考试');
id | username | sex | hobby |
±—±----------±-----±------------------------+
| 7 | 杨得港 | male | 上课,写作业,考试 |
| 8 | 李帅 | male | 考试
truncate table t1;
insert into t1(username,hobby) values('杨得港','上课,写作业,考试'),('李帅','考试');
id | username | sex | hobby |
±—±----------±-----±------------------------+
| 1 | 杨得港 | male | 上课,写作业,考试 |
| 2 | 李帅 | male | 考试
注意:delete from 表名 是删除表中数据,不清除表中的约束条件
delete from t1 where id = 1;
select * from t1 where id = 2; 在删除之前检查数据是否存在
改变数据
语法:
update 表 set 字段=值 where 条件
update 表名 set 字段=值, 字段2=值2 where 条件;
update t1 set id = 1,hobby='写作业,考试' where id = 2;
查询数据search
company.employee
员工id id int
姓名 emp_name varchar
性别 sex enum
年龄 age int
入职日期 hire_date date
岗位 post varchar
职位描述 post_comment varchar
薪水 salary double
办公室 office int
部门编号 depart_id int
#创建表
create table employee(
id int not null unique auto_increment,
emp_name varchar(20) not null,
sex enum('male','female') not null default 'male', #大部分是男的 age int(3) unsigned not null default 28,
hire_date date not null,
post varchar(50),
post_comment varchar(100),
salary double(15,2), office int, #一个部门一个屋子
depart_id int
);
insert into employee(emp_name,sex,age,hire_date,post,salary,office,depart_id) values
('egon','male',18,'20170301','老男孩驻沙河办事处外交大使',7300.33,401,1), #以下是教学部
('alex','male',78,'20150302','teacher',1000000.31,401,1),
('wupeiqi','male',81,'20130305','teacher',8300,401,1),
('yuanhao','male',73,'20140701','teacher',3500,401,1),
('liwenzhou','male',28,'20121101','teacher',2100,401,1),
('jingliyang','female',18,'20110211','teacher',9000,401,1),
('jinxin','male',18,'19000301','teacher',30000,401,1),
('成龙','male',48,'20101111','teacher',10000,401,1),
('歪歪','female',48,'20150311','sale',3000.13,402,2),#以下是销售部门
('丫丫','female',38,'20101101','sale',2000.35,402,2),
('丁丁','female',18,'20110312','sale',1000.37,402,2),
('星星','female',18,'20160513','sale',3000.29,402,2),
('格格','female',28,'20170127','sale',4000.33,402,2),
('张野','male',28,'20160311','operation',10000.13,403,3), #以下是运营部门
('程咬金','male',18,'19970312','operation',20000,403,3),
('程咬银','female',18,'20130311','operation',19000,403,3),
('程咬铜','male',18,'20150411','operation',18000,403,3),
('程咬铁','female',18,'20140512','operation',17000,403,3)
;
简单查询:
select * from 表名;
select 字段1,字段2 from 表名;
重命名字段
select 字段1,字段2 as 新名 from 表名;
select 字段1,字段2 新名 from 表名; 默认将字段重命名为新名
避免重复
select distinct 字段名 from 表名;
select distinct 字段名1,字段名2 from 表名;
通过四则select运算查询
select emp_name, salary*12 from employee;
select emp_name, salary*12 as Annual_salary from employee;
select emp_name, salary*12 Annual_salary from employee;
定义显示格式
# CONCAT() -------函数--------用于连接字符串
select concat('姓名: ',emp_name,' 年薪: ', salary*12) as Annual_salary from employee;
select concat(emp_name,salary) from employee;
select concat(emp_name,':',salary) from employee;
# CONCAT_WS() 第一个参数为分隔符
select concat_ws(':',emp_name,salary*12) as Annual_salary from employee;
# 结合case语句: 使用判断逻辑
select
(
case # if判断
when emp_name = 'jingliyang' then
emp_name
when emp_name = 'alex' then
CONCAT(emp_name,'_BIGSB')
else
concat(emp_name,'SB')
end # 判断结束
) as new_name
from
employee;
小练习:
1 查出所有员工的名字,薪资,格式为
<名字:egon> <薪资:3000>
2 查出所有的岗位(去掉重复)
3 查出所有员工名字,以及他们的年薪,年薪的字段名为annual_year
答案:
1.select concat('<名字:',emp_name,'> ',' <薪资:',salary,'>') from employee;
2. select distinct post from employee;
3.select emp_name,salary*12 as annual_year from employee;
或select emp_name,salary*12 annual_year from employee;
where 约束
where字句中可以使用:
\1. 比较运算符:
> < >= <= <> != =
\2.范围
between and 值在之间
in( , , ) 值是 或 或
\4. 模糊匹配
like :
通配符可以是 % 或 _
% 表示任意多字符
_ 表示一个字符
regexp
'^a'
'g$'
\5. 逻辑运算符:
在多个条件直接可以使用逻辑运算符 not and or (按照优先级)
select * from employee where salary not in (10000,20000); # 出去10000,20000的其他数值
select * from employee where salary not in (10000,20000) and age = 18; # 薪资不是10000或20000 并且年龄为18
select * from employee where sex = 'male' or post = 'teacher' or salary>10000; # 满足一个条件即可
#1:单条件查询
select emp_name from employee
where post='sale';
#2:多条件查询
select emp_name,salary from employee
where post='teacher' and salary>10000;
#3:关键字between and
select emp_name,salary from employee
where salary between 10000 and 20000; # 在10000-20000之间
select emp_name,salary from employee
where salary NOT between 10000 and 20000;
#4:关键字IS NULL(判断某个字段是否为NULL不能用等号,需要用IS)
select emp_name,post_comment from employee
where post_comment IS NULL;
select emp_name,post_comment from employee
where post_comment IS NOT NULL;
select emp_name,post_comment from employee
where post_comment=''; 注意''是空字符串,不是null
ps:
执行
update employee set post_comment='' where id=2;
再用上条查看,就会有结果了
#5:关键字IN集合查询
select emp_name,salary from employee
where salary=3000 OR salary=3500 OR salary=4000 OR salary=9000 ;
select emp_name,salary from employee
where salary IN (3000,3500,4000,9000) ;
select emp_name,salary from employee
where salary NOT IN (3000,3500,4000,9000) ;
#6:关键字LIKE模糊查询
通配符’%’ 表示任意长度的任意内容
select * from employee
where emp_name like 'eg%';
select * from employee
where emp_name like '%i%';
通配符’_’ 一个字符长度的任意内容
select * from employee
where emp_name like 'al_';
Empty set (0.00 sec)
select * from employee
where emp_name like 'al__';
#7:使用正则表达式查询 regexp
select * from employee where emp_name regexp '^ale';
select * from employee where emp_name regexp 'on$';
select * from employee where emp_name regexp 'm{2}';
小结:对字符串匹配的方式
where emp_name = 'egon';
where emp_name like 'yua%';
where emp_name regexp 'on$';
练习:
-
查看岗位是teacher的员工姓名、年龄
select emp_name,age from employee where post = 'teacher';
-
查看岗位是teacher且年龄大于30岁的员工姓名、年龄
select emp_name,age from employee where post='teacher' and age>30;
-
查看岗位是teacsher且薪资在9000-10000范围内的员工姓名、年龄、薪资
select emp_name,age,salary from employee where post='teacher' and salary between 9000 and 10000;
-
查看岗位描述不为NULL的员工信息
**关键字is null (判断某个字段是否为null不能用等号,需要用is)** 不能使用 !=
select * from employee where post_comment is not null;
-
查看岗位是teacher且薪资是10000或9000或30000的员工姓名、年龄、薪资
select emp_name,age,salary from employee where post='teacher'and salary in(10000,9000,30000);
-
查看岗位是teacher且薪资不是10000或9000或30000的员工姓名、年龄、薪资
select emp_name,age,salary from employee where post='teacher' and salary not in (10000,9000,30000);
-
查看岗位是teacher且名字是jin开头的员工姓名、年薪
select emp_name,salary*12 from employee where post='teacher' and emp_name like 'jin%';
分组 聚合
# **根据谁分组,可以求这个组的总人数、最大值、最小值、平均值、求和,但是这个求出来的值只是和分组字段对应**
# **不和其他任何字段对应,这个时候查出来的所有其他字段都不生效**
group by
单独使用group by关键字分组
select post from employee group by post;
注意:我们按照post字段分组,那么select查询的字段只能是post,想要获取组内的其他相关信息,需要借助函数
group by 与聚合函数一起使用
set @@global.sql_mode
=’STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION’;
聚合函数
1.count 计数
select post,count(id) from employee group by post;#按照岗位分组,并查看每个组有多少人
select sex,count(id) from employee group by sex; # 按照性别分组,并查看分组的人数
2.max 求最大值
select post,max(salary) from employee group by post; # 每一个部门工资最高的人
3.min 求最小值
select post,min(salary) from employee group by post; # 每一个部门工资最低的人
4.sum 求和
select post,sum(salary) from employee group by post; # 每个部门的工资和
5.avg
select post,avg(salary) from employee group by post; # 求每个部门的平均薪资
6.group by关键字和group_concat()函数一起使用
select post,group_concat(emp_name) from employee group by post; #按照岗位分组,并查看组内所有成员名
select post,group_concat(emp_name) as emp_members from employee group by post;
练习:
-
查询岗位名以及岗位包含的所有员工名字
select post,group_concat(emp_name) from employee group by post;
-
查询岗位名以及各岗位内包含的员工个数
select post,count(id) from employee group by post;
-
查询公司内男员工和女员工的个数
select sex,count(id) from employee group by sex;
-
查询岗位名以及各岗位的平均薪资
select post,avg(salary) from employee group by post;
-
查询岗位名以及各岗位的最高薪资
select post,max(salary) from employee group by post;
-
查询岗位名以及各岗位的最低薪资
select post,min(salary) from employee group by post;
-
查询男员工与男员工的平均薪资,女员工与女员工的平均薪资
select sex,avg(salary) from employee group by sex;
过滤
having 过滤语句
- 在having条件中可以使用聚合函数,但是在where不行
- 求各部门平均薪资大于10000的部门
select post,avg(salary) from employee group by post having avg(salary)>10000;
如果使用where条件语句
select post,avg(salary) from employee where avg(salary)>10000 group by post;
ERROR 1111 (HY000): Invalid use of group function
-
适合筛选符合条件的某一组数据,而不是一行数据
-
先分组 再过滤:
- 求平均薪资大于xx的部门,求人数大于x x的性别,求大于xx人的年龄段
练习:
# 查询各岗位内包含的员工个数小于2的岗位名、岗位内包含员工名字、个数
select post,group_concat(emp_name),count(id) from employee group by post having count(id) <2;
# 查询各岗位平均薪资大于10000的岗位名、平均工资
select post,avg(salary) from employee group by post having avg(salary)>10000;
# 查询各岗位平均薪资大于10000且小于20000的岗位名、平均工资
select post,avg(salary) from employee group by post having avg(salary)>10000 and avg(salary)<20000;
查询排序
order by
按单列排序
- 按照薪资排序(默认升序)
select * from employee order by salary;
select * from employee order by salary asc;
- 按照薪资排序(降序)
select * from employee order by salary desc;
按多列排序
- 先按照age排序(升序),如果年纪相同,则按照薪资排序(升序)
select * from employee order by age,salary;
- 先按照age排序(降序),如果年龄相同,则按照薪资排序(降序)
select * from employee order by age desc,salary desc;
练习
# 查询所有员工信息,先按照age升序排序,如果age相同则按照hire_date降序排序
select * from employee order by age,hire_date desc;
# 查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资升序排列
select post,avg(salary) from employee group by post having avg(salary)>10000 order by avg(salary);
# 查询各岗位平均薪资大于10000的岗位名、平均工资,结果按平均薪资降序排列
select post,avg(salary) from employee group by post having avg(salary)>10000 order by avg(salary) desc;
限制查询的记录数
limit m,n
- 从m+1项开始,取n项
- 如果不写m,默认为0
取薪资最高的第一名
select * from employee order by salary desc limit 1; # 从0开始取一条
取薪资最高的前三名
select * from employee order by salary desc limit 3; # 从0开始取三条
取薪资最高的第三名
select * from employee order by salary desc limit 2,1; # 从2开始取一条
- limit n offset m
select * from employee order by salary desc limit 1 offset 2; # 从2开始取一条