文章目录
前言一、DML 增删改添加数据修改数据删除数据 二、DQL 查询基本查询条件查询聚合函数(count、max、min、avg、sum)分组查询(group by)排序查询(order by)分页查询(limit)DQL 语句练习 三、SQLDCL 权限控制约束案例多表查询事务存储引擎字符串函数数值函数日期函数流程函数前言
本篇选自本人前段时间对MySQL的皮毛学习,在这里进行一个简单的汇总,希望能对读者有或多或少的帮助,若有什么不懂的知识盲区,可在评论区交流讨论。
一、DML 增删改
添加数据
给指定字段添加数据 insert into 表名(字段1,字段2…) values (值1,值2…);insert into employee(id, workno, name, gender, age, idcard, entrydate) values (1,'1','Itcase','男',10,'012345678998765432','-9-19');
查看表中的值
select * from employee;
给全部字段添加数据 insert into 表名 values (值1,值2…);
insert into employee values(2,'2','张无忌','男',18,'012345678901234567','-9-19');
批量添加数据 inset into 表名 (字段1,字段2…) values (值1,值2…),(值1,值2…),(值1,值2…);
#insert into 表名 values (值1,值2...),(值1,值2...),(值1,值2...);insert into employee values(3,'3','韦一笑','男',28,'012345678901234567','-9-19'),(4,'4','张三丰','男',38,'012345678901234567','-9-19');
修改数据
update 表名 set 字段1=值1,字段2=值2,… [where 条件];
修改id为1的数据,将name修改为itheima
update employee set name = 'itheima' where id=1;
修改id为1的数据,将name修改为小昭,gender修改为女
update employee set name='小昭',gender='女' where id=1;
将所有的员工入职日期修改为-01-01
update employee set entrydate='-01-01';
删除数据
delete from 表名 [where 条件]
删除 gender为女的员工
delete from employee where gender='女';
删除所有员工
delete from employee;
删除employee表
drop table employee;
二、DQL 查询
数据准备
create table emp(idint comment '编号',worknovarchar(10) comment '工号',name varchar(10) comment '姓名',genderchar(1) comment '性别',age tinyint unsigned comment '年龄',idcardchar(18) comment '身份证号',workaddress varchar(50) comment '工作地点',entrydate datecomment '入职时间') comment '员工表';
插入数据
insert into emp (id, workno, name, gender, age, idcard, workaddress, entrydate)values (1,'1','柳岩','女',20,'123654879654123658','北京','2000-01-01'),(2,'2','张无忌','男',18,'123654879654123611','北京','-09-01'),(3,'3','韦一笑','男',38,'123654879654123650','上海','-08-01'),(4,'4','赵敏','女',18,'123654879654123658','北京','-12-01'),(5,'5','小昭','女',16,'123654879654120008','上海','-07-01'),(6,'6','杨逍','男',28,'12365487965418','北京','-01-01'),(7,'7','范瑶','男',40,'123654879650023658','北京','-05-01'),(8,'8','黛绮丝','女',38,'123654870054123658','天津','-05-01'),(9,'9','范凉凉','女',45,'123654879654123658','北京','-04-01'),(10,'10','陈友谅','男',53,'123054879654123658','上海','-01-01'),(11,'11','张士诚','男',55,'103654879654123658','江苏','-05-01'),(12,'12','常遇春','男',32,'120654879654123658','北京','-02-01'),(13,'13','张三丰','男',88,'123654879654123658','江苏','-11-01'),(14,'14','灭绝','女',65,'123650000654123658','西安','-05-01'),(15,'15','胡青牛','男',70,'123654879654120000','西安','-04-01'),(16,'16','周芷若','女',18,null,'北京','-06-01');
基本查询
select 字段列表 from 表名列表
查询多个字段 select 字段1,字段2… from 表名;
select * from 表名;
设置别名
select 字段1 [as 别名1],字段2 [as 别名2]... from 表名;
去除重复记录
select distinct 字段列表 from 表名;
(1) 查询指定字段 name,workno,age 返回
select name,workno,age from emp;
(2)查询所有字段返回
select id,workno, name, gender, age, idcard, workaddress, entrydate from emp;select * from emp;
(3)查询所有员工的工作地址,起别名
select workaddress as '工作地址' from emp;select workaddress '工作地址' from emp; #as可省略
(4)查询公司员工的上班地址(不要重复)
select distinct workaddress '工作地址' from emp;
条件查询
select 字段列表 from 表名 where 条件列表;
查询年龄等于88的员工
select * from emp where age=88;select id,workno, name, gender, age, idcard, workaddress, entrydate from emp where age=88;
查询年龄小于20的员工信息
select * from emp where age<20;
查询小于等于20的员工信息
select * from emp where age<=20;
查询没有身份证号的员工信息
select * from emp where idcard is null;
查询有身份证号的员工信息
select * from emp where idcard is not null;
查询年龄不等于88的员工信息
select * from emp where age!=88;select * from emp where age<>88;
查询年龄在15岁(包含)到20岁(包含)之间的员工信息
select * from emp where age>=15 && age <=20;select * from emp where age>=15 and age <=20;select * from emp where age between 15 and 20;
查询性别为女且年龄小于25岁的员工信息
select * from emp where gender='女' and age<25;
查询年龄等于18或20或40的员工信息
select * from emp where age=18 || age =20 || age=40;select * from emp where age=18 or age =20 or age=40;select * from emp where age in(18,20,40);
查询名字为俩个字的员工信息 一个’_‘代表一个字符
select * from emp where name like '__';
11.查询身份证号最后一位是0的员工信息 一个’%‘代表任意字符
select * from emp where idcard like '%0';select * from emp where idcard like '_________________0';
聚合函数(count、max、min、avg、sum)
select 聚合函数(字段列表) from 表名;
统计该企业员工数量
select count(*) from emp;
统计该企业员工的平均年龄
select avg(age) from emp;
统计该企业员工的最大年龄
select max(age) from emp;
统计该企业员工的最小年龄
select min(age) from emp;
统计西安地区员工的年龄之和
select sum(age) from emp where workaddress='西安';
分组查询(group by)
select 字段列表 from 表名 [where 条件] group by 分组字段名 [having 分组后过滤条件];
根据性别分组,统计男性员工和女性员工
select gender,count(*) from emp group by gender;
根据性别分组,统计男性员工和女性员工的平均年龄
select gender,avg(age) from emp group by gender;
查询年龄小于45的员工,并根据工作地址分组,获取员工数量大于等于3的工作地址
select workaddress, count(*) from emp where age<45 group by workaddress having count(*)>=3;
排序查询(order by)
select 字段列表 from 表名 order by 字段1 排序方式1,字段2 排序方式2;
根据年龄对公司的员工进行升序排序
select * from emp order by age asc;select * from emp order by age; #默认会升序select * from emp order by age desc; #降序
根据入职时间,对员工进行降序排序
select * from emp order by entrydate desc;
根据年龄对公司的员工进行升序排序,年龄相同,再按照入职时间进行降序排序
select * from emp order by age asc,entrydate desc;
分页查询(limit)
select 字段列表 from 表名 limit 起始索引,查询记录数;
查询第一页员工数据,每页展示10条记录
select * from emp limit 0,10;select * from emp limit 10; #可以省略起始索引0
查询第二页员工数据,每页展示10条记录 起始索引=(查询页码-1)*每页显示记录数
select * from emp limit 10,10;
DQL 语句练习
DQL 语句执行顺序:from->where->group by->select->order by->limit
查询年龄为20,21,22,23岁的女性员工信息。
select * from emp where age in(20,21,22,23) and gender='女';
查询性别为男,并且年龄在20-40岁(含)以内的姓名为三个字的员工。
select * from emp where gender='男'and age>20 and age<=40 and name like '___';
统计员工表中,年龄小于60岁的,男性员工和女性员工的人数。
select gender, count(*) from emp where age<60 group by gender;
查询所有年龄小于等于35岁员工的姓名和年龄,并对查询结果按年龄升序排序,如果年龄相同按入职时间降序排序
select name,age from emp where age<=35 order by age asc,entrydate desc ;
查询性别为男,且年龄在20-40岁(含)以内的前3个员工信息,对查询的结果按年龄升序排序,年龄相同按入职时间升序排序.
select * from emp where gender='男' and age<=40 and age>=20 order by age asc ,entrydate desc limit 3;
三、SQL
查询用户
user mysql; select * from user;
直接选中左框中的mysql,找到user表,双击即可查看用户
创建用户
create user '用户名'@'主机名' identified by '密码';
修改用户密码
alter user '用户名'@'主机名' identified with mysql_native_password by '新密码';
删除用户
drop user '用户名'@'主机名';
创建用户itcast,只能够在当前主机localhost访问,密码123456;
create user 'itcase'@'localhost' identified by '123456';
创建用户heima,可以在任意主机访间该数据库,密码123456;
create user ' heima' @'%' identified by '123456';
修改用户heima的访问密码为1234;
alter user ' heima'@'%' identified with mysql_native_password by '1234';
删除itcast@localhost用户;
drop user 'itcase'@'localhost';
DCL 权限控制
查询权限show grants for '用户名'@'主机名';
授予权限
grant 权限列表 on 数据库名.表名 to '用户名'@'主机名';
撤销权限
remove 权限列表 on 数据库名.表名 from '用户名'@'主机名';
约束案例
约束名称 描述 关键字非空约束 保证列中所有数据不能有null值 NOT NULL唯一约束 保证列中所有数据各不相同 UNIQUE主键约束 主键是一行数据的唯一标识,要求非空且唯一PRIMARY KEY检查约束 保证列中的值满足某一条件 CHECK默认约束 保存数据时,未指定值则采用默认值 DEFAULT外键约束 外键用来让两个表的数据之间建立链接,保证数据的一致性和完整性FOREIGN KEY
员工表 在创建表时添加约束
create table emp1 (id int primary key auto_increment , -- 员工id,主键且自增长ename varchar(50) not null unique , -- 员工姓名,非空并且唯一joindate date not null , -- 入职日期,非空salary double(7,2) not null , -- 工资,非空bonus double(7,2) default 0 -- 奖金,如果没有奖金默认为0);
– 例:建完表后添加约束 alter table 表名 modify 字段名 数据类型 not null;
– 删除约束: alter table 表名 modify 字段名 数据类型;
show databases ;use itcase;show tables ;select * from emp1;drop table dept;insert into emp1(id, ename, joindate, salary, bonus) values (1,'张三','1999-11-11',8800,5000);
添加约束
(1) 创建表时添加外键约束
CREATE TABLE表名(列名 数据类型,...[CONSTRAINT] [外键名称] FOREIGN KEY(外键列名)REFERENCES 主表(主表列名));
(2) 建完表后添加外键约束
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY(外键字段名称)REFERENCES 主表名称(主表列名称);
例:alter table emp add constraint fk_emp_dept foreign key(dep_id) references dept(id);
删除约束
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;例:alter table emp drop foreign key fk_emp_dept;
练习
-- 部门表create table dept (id int primary key auto_increment , -- 部门id,主键且自增长dep_name varchar(20) , -- 部门名addr varchar(20) -- 部门地址);-- 员工表create table emp (id int primary key auto_increment , -- 员工id,主键且自增长name varchar(20) , -- 员工姓名age int,dep_id int, -- 所属部门id-- 添加外键 dep_id,关联dept表的id主键constraint fk_emp_dept foreign key(dep_id) references dept(id));-- 添加俩个部门insert into dept(dep_name, addr) values ('研发部','广州'),('销售部','深圳');-- 添加员工 dep_id 表示员工所在的部门insert into emp(name,age,dep_id) values ('张三',20,1),('李四',20,1),('王五',20,1),('赵六',20,2),('孙七',20,2),('周八',20,2);select * from emp;
多表查询
隐式内连接select 字段列表 from 表1,表2… where 条件;
select emp.id,emp.name,emp.age,dept.dep_name from emp,dept where emp.dep_id=dept.id;select t1.id,t1.name,t1.age,t2.dep_name from emp t1,dept t2 where t1.dep_id=t2.id;
显示内连接
select 字段列表 from 表1 [inner] join 表2 on 条件;
select * from emp inner join dept on emp.dep_id=dept.id;select * from emp join dept on emp.dep_id=dept.id; #inner可省略
左外连接
select 字段列表 from 表1 left [outer] join 表2 on 条件;
左外连接:相当于查询A表所有数据和交集部分数据
select * from emp left join dept on emp.dep_id=dept.id;
右外连接
select 字段列表 from 表1 right [outer] join 表2 on 条件
右外连接:相当于查询B表所有数据和交集部分数据
select * from emp right join dept on emp.dep_id=dept.id;
子查询:
单行单列:作为条件值,使用=、!=、>、<等进行条件判断
select 字段列表 from 表 where 字段名=(子查询);
(1) 查询‘财务部’所有的员工信息 emp是员工表 dept是部门表
select id from dept where dname='财务部'; 获取财务部的部门id号select * from emp where dep_id=(select id from dept where dname='财务部');
多行单列:作为条件值,使用in等关键字进行条件判断
select 字段列表 from 表 where 字段名 in (子查询);
(2) 查询‘财务部’和‘市场部’所有的员工信息 emp是员工表 dept是部门表
select id from dept where dname='财务部' or dname='市场部'; 获取财务部和市场部的部门id号select * from emp where dep_i in (select id from dept where dname='财务部' or dname='市场部');
多行多列:作为虚拟表
select 字段列表 from (子查询) where 条件;
(3) 查询入职日期是’-11-11’之后的员工信息和部门信息
select * from emp where join_data>'-11-11'; 获取入职日期是'-11-11’之后的员工信息select * from (select * from emp where join_data>'-11-11') t1,dept where t1.dep_id=dept.id;
事务
1. 开启事务start transaction;
或者begin
2. 提交事务
commit
;3. 回滚事务
rollback
;
-- 创建账户表drop table if exists account;create table account(id int primary key auto_increment,name varchar(10),money double(10,2));select * from account;-- 添加数据insert into account(name,money) values('张三',1000),('李四',1000);update account set money=1000; #设置 张三李四 余额变为1000
转账操作
(1)开启事务
begin ;
(2)查询李四的余额
select money from account where name='李四';
(3)李四金额 -500
update account set money=money-500 where name='李四';
(4)张三金额 +500
update account set money=money+500 where name='张三';
提交事务
commit ;
回滚事务
rollback ;
事务四大特征:
原子性(Atomicity):事务是不可分割的最小操作单位,要么同时成功,要么同时失败
一致性(Consistency):事务完成时,必须使所有的数据都保持一致状态
隔离性(lsolation) :多个事务之间,操作的可见性
持久性(Durability):事务一旦提交或回滚,它对数据库中的数据的改变就是永久的
查询事务的默认提交方式
select @@autocommit;
#1为自动 0为手动 mysql数据库默认为自动 修改事务的提交方式
set @@autocommit=0;
# 0 为手动方式 即需要手动调用 commit;
并发事务问题:
脏读:一个事务读到另外一个事务还没有提交的数据。不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同,称之为不可重复幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了"幻影”。
事务隔离级别:
脏读 不可重复读 幻读read uncommitted有 有 有read committed 01 1repeatable read00 1serializable 00 0
查看事务隔离级别
select @@transaction_isolation;
设置事务隔离级别
set [session | global] transaction isolation level {read uncommitted | read committed | repeatable read | serializable }set session transaction isolation level read uncommitted ;set session transaction isolation level repeatable read ;
存储引擎
查询建表语句 —默认存储引擎:InnoDBshow create table account;
查询当前数据库支持的存储引擎
show engines ;
创建表my_myisam,并指定MyISAM存储引擎
create table my_myisam(id int,name varchar(10))engine =MyISAM;
字符串函数
concat 字符串连接select concat('hello','MySQL');
lower 都转为小写
select lower('Hello');
upper 都转为大写
select upper('Hello');
lpad 向左填充
select lpad('01',5,'hadia'); # 将字符串’hadia‘给字符串’01‘ 左边填充至5个字符
rpad 向右填充
select rpad('01',5,'hadia');
trim 去除首尾的空格
select trim(' hello to me ');
substring 截取字符
select substring('hello mysql',1,5); #截取字符串的 第一个位置开始的5个字符
(1)案例:由于业务需求变更,企业员工的工号统一为5位数,目前不足5位数的全部在前面补0,如1号员工的工号应该为00001
update user set name=lpad(name,5,'0'); # 因为id为int型需要string型,所以这里用name代替
数值函数
ceil() 向上取整select ceil(1.1);
floor(x) 向下取整
select floor(1.9);
mod(x,y) 返回x/y的模
select mod(3,4);
rand() 返回0~1内的随机数
select rand();
round(x,y) 求参数x的四舍五入的值,保留y位小数
select round(2.345,2);
(2)案例:通过数据库的函数,生成一个六位数的随机验证码
select lpad(round(rand()*1000000,0),6,'0');
日期函数
curdate() 返回当前日期select curdate();
curtime() 返回当前时间
select curtime();
now() 返回当前日期和时间
select now();
year(date) 获取指定date的年份
select year(now());
month(data) 获取指定date的月份
select month(now());
day(date) 获取指定date的日期
select day(now());
date_add(date,interval expr type) 返回一个日期/时间值加上一个时间间隔expr后的时间值
select date_add(now(),interval 70 day ); #从现在日期往后推70天 interval是固定值,70是变值,day是可变的时间单位 month、year
datediff(date1,date2) 返回起始时间date1和结束时间date2之间的天数
select datediff('-10-1','-9-26');
(3)案例:查询所有员工的入职天数,并根据入职天数倒序排序
select name,datediff(curdate(),entrydate) as 'days' from emp order by days desc; # entrydate为员工表中的入职天数(这里没创建)
流程函数
if(value,t,f) 如果value为true,则返回t,否则返回fselect if(true,'ok','error');select if(false,1,0);
ifnull(value1,value2) 如果value1不为空,返回value1,否则返回value2
select ifnull('ok','default');select ifnull(' ','default');select ifnull(null,0);
case where[val1] then [res1]… else [default] end 如果val1为true,返回res1,否则返回default默认值
(1)需求:查询emp表的员工姓名和工作地址(北京/上海—> 一线城市,其他----> 二线城市)
select name,(case workaddress when '北京' then '一线城市' when '上海' then '一线城市' else '二线城市' end) as '工作地址' from emp; # workaddress为表中的工作地址,emp为表名
case [expr] when [val1] then [res1]… else [default] end 如果exper的值等于val1,返回res1,… 否则返回default默认值
(1)案例:统计班级各个学员的成绩,展示的规则如下: >=85,展示优秀 >=60,展示及格 否则展示不及格
create table score(id int comment 'ID', # comment后面加注释name varchar(20) comment '姓名',math int comment '数学',english int comment '英语',chinese int comment '语文') comment '学员成绩表';insert into score(id,name, math,english,chinese) values (1,'Tom',67,88,95 ),(2,'Rose',23,66,90),(3,'Jack',56,98,76);select id,name,(case when math>=85 then '优秀' when math>=60 then '及格' else '不及格' end) as '数学',(case when english>=85 then '优秀' when english>=60 then '及格' else '不及格' end) as '英语',(case when chinese>=85 then '优秀' when chinese>=60 then '及格' else '不及格' end) as '语文'from score;