数据库操作(二)
数据库操作(二)
1.MySQL行(记录)操作
插入(增加)数据
1.插入完整数据
语法1:
insert into 表名(字段1,字段2..字段n) values(值1,值2..值n);
#字段和值要一一对应
语法2:
insert into 表名 values(值1,值2..值n);
#表名后不定义列名,则按顺序给所有列添加值
2.指定字段插入数据
语法:
insert into 表名(字段1,字段2..) values(值1,值2..)
3.插入多条记录
语法:
insert into 表名 values
(值1,值2,值3...值n),
(值1,值2,值3...值n),
(值1,值2,值3...值n); #插入多条记录用逗号分隔
4.插入查询结果
语法:
insert into 表名(字段1,字段2..字段n)
select (字段1,字段2..字段n) from 表2
where 条件;
#将从表2中查询的结果插入到表中,查询数据要和指定的字段对应好
5.增加字段
语法:
alter table 表名
add 字段名 数据类型 约束条件,
add 字段名 数据类型 约束条件; #增加记录
alter table 表名
add 字段名 数据类型 约束条件 first; #增加记录到第一个位置
alter table 表名
add 字段名1 数据类型 约束条件 after 字段名2;
#将字段1添加到字段2后面
更新(修改)数据
语法:
update 表名 set
字段1 = 值1,
字段2 = 值2,
where 条件;
#如果不加任何条件,则会将表中所有记录全部修改
alter table 表名
modify 字段名 数据类型 约束条件;
alter table 表名
change 旧字段名 新字段名 新数据类型 新约束条件;
#在更改时不更改数据类型和约束条件则继续写上原来的
删除数据
语法:
delete from 表名 where 条件;
#如果不加条件,则删除表中所有记录
delete from 表名;
#删除所有记录,有多少条记录就执行多少次删除操作 --不推荐
truncate table 表名;
#删除表后在创建一张相同的空表 --推荐
alter table 表名 drop 字段名;
#删除字段
针对外键关系补充
删除或修改被关联字段:
1.查看外键关系名称:
show create table 表1;
# 可以查看到系统命名的外键名称
2.删除外键关系
alter table 表1 drop foreign key 外键名称;
3.删除字段:
alter table 表2 drop 字段名;
4.添加字段:
alter table 表2 add 字段名 数据类型 约束条件;
5.创建表完成后添加外键关系:
alter table 表1 add foreign key(表1字段) references 表2(表2被关联字段);
创建外键时指定外键名称:
create table 表名(字段1 类型,
字段2 类型,
字段3 类型,
constraint 指定的外键名称 foreign key(表1字段) references 表2(表2被关联字段);
查询数据
-单表查询
单表查询语法
查询数据的本质:mysql到本地硬盘找到对应文件,然后打开文件,按照给出的查询条件查找需要的数据
语法:
select * from 表名; #查询表中所有记录
select distinct 字段1,字段2...from 库名.表名
where 条件 #从表中找符合条件的数据记录
group by 字段 #分组
having #筛选,过滤执行select后的字段
order by #将结果按后面的字段进行排序
limit #限制查询出来的数据记录的条数
关键字的执行优先级
关键字的执行优先级
from
where
group by
having
select distinct
order by
limit
1.找到表:from
2.使用where指定的约束条件,到文件/表中取出一条条记录
3.将取出的记录进行分组group by,如果没有group by,则整体作为一组
4.将分组的结果进行having过滤
5.执行select
6.去重
7.将结果按条件排序:order by
8.限制结果的显示条数
简单查询
通过创建一个员工表employee,来进行查询
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,
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(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);
查询操作
1.查询所有记录
select * from employee;
select id,name,sex,age,hire_date,post,post_comment,salary,office,depart_id from employee;
通过四则运算查询(+,-,*,/)
select salary*12 from employee;
自定义显示格式
#concat()函数用于连接字符串
#concat_ws()第一个参数作为分割符来进行字符串拼接
select concat('姓名:',name,'月薪:'salary) from employee;
select concat_ws(':',name,salary) from empolyee;
#用冒号将name和salary连接起来
2.where条件
① 比较运算符: > < >= <= !=等同于<>
select name from employee where post = 'sale';
② between..and.. #写的是一个闭区间
select * from employee where id between 10 and 15;
③ in(集合)
select * from employee where id in(1,3,6); #查找满足集合内条件的记录
④ like 关键字模糊查询
通配符 % #匹配所有任意字符
select * from employee where name like "wu%";
通配符 _ #匹配任意一个字符
select * from employee where name like 'al__';
⑤ and or not 逻辑运算符
select * from employee where id>10 and name like "al%";
select * from employee where not id>10;
⑥ is null
select name,post_comment from employee where post_comment is null;
#判断某个字段是否为null只能用is
3.分组查询(group by)
分组:将所有记录按照某个相同字段进行归类,比如按照性别进行分组等.分组发生在where之后,即分组时基于where之后得到的记录而进行的
group by一般会与聚合函数一起使用
select post,max(salary) from employee group by post;
#统计每个岗位的名称以及最高工资
分组时可以跟多个条件,那么多个条件同时重复才算是一组,多条件用逗号分隔
only_full_group_by模式
如果设置了这个模式,那么select后面只能写group by后面的分组字段和聚合函数统计结果
聚合函数:将一列数据作为一个整体,进行纵向的计算
count:计算个数 (一般选择非空的列:主键)
max:计算最大值
min:计算最小值
sum:求和
avg:计算平均值
#使用设置了unique约束的字段分组,则分组无意义,多个记录之间的某个字段值相同,该字段通常作为分组的依据
4.having 分组后再过滤
select post,max(salary) from employee group by post having max(salary) > 20000;
#where和having的区别:
#1.where在分组之前进行限定,如果不满足条件,则不参与分组
# having在分组之后进行限定,如果不满足条件,则不会被查询出来
#2.where后面不可以跟聚合函数,having可以进行聚合函数的判断
5.去除重复(distinct):
select distinct post from employee;
#注意:select的字段必须卸载distinct的后面,如果写了多个字段,比如:
select post,id from employee;
#结果并没去重,post和id两个组合在一起同时重复的才算做重复数据
6.order by 排序
select * from employee order by age;
select * from employee order by age desc;
select * from employee order by age asc,salary desc;
排序方式:
升序(默认): asc
降序: desc
#如果有多个排序条件,则当前的条件值一样时,才会判断第二条件.
7.limit 限制
select * from employee order by salary desc limit 3;
select * from employee order by salary desc limit0,5;
limit 开始的索引:每页查询的条数
8.regexp 使用正则表达式查询
select * from employee where name regexp '^ale';
select * from employee where name regexp 'on$';
-多表查询
通过建立两张表:
#部门表
create table dep(
id int,
name varchar(20)
);
#员工表
create table emp(
id int primary key auto_increment,
name varchar(20),
sex enum('male','female') not null default 'male',
age int,
dep_id int
);
#给两个表插入一些数据
insert into dep values
(200,'技术'),
(201,'人力资源'),
(202,'销售'),
(203,'运营');
insert into emp(name,sex,age,dep_id) values
('egon','male',18,200),
('alex','female',48,201),
('wupeiqi','male',38,201),
('yuanhao','female',28,202),
('liwenzhou','male',18,200),
('jingliyang','female',18,204);
多表连接查询
语法:
select 字段列表 from 表1 inner|left|right join 表2
on 表1.字段 = 表2.字段
1.交叉连接:不适用任何匹配条件.生成笛卡尔积
笛卡尔积,通俗点说就是指包含两个集合中任意取出两个元素构成的组合的集合.
将两表所有的数据一一对应,生成一张大表.
select * from dep,emp; #两个表拼在一起
2.内连接:只连接匹配的行
①隐式内连接:使用where条件消除无用数据
select * from dep,emp where dep.id = emp.dep_id; #找到两表之间对应的关系记录
select * from dep,emp where dep.id = emp.dep_id and dep.name = '技术'; # 筛选部门名称为技术的大表中的记录
select emp.name from dep,emp where dep.id = emp.dep_id and dep.name = '技术'; #哪到筛选后的记录的员工姓名字段数据
②显式内连接
语法: select 字段列表 from 表名1 inner join 表名2 on 条件;
第一步:连表
select * from dep inner join emp on dep.id=emp.dep_id;
第二步:过滤
select * from dep inner join emp on dep.id=emp.dep_id where dep.name = '技术';
第三步:找对应字段数据
select emp.name from dep inner join emp on dep.id=emp.dep_id where dep.name = '技术';
#注意条件:1从哪些表中查询数据 2.条件是什么 3.查询哪些字段
3.外连接查询
①左外连接(优先显示左表全部记录)
语法 select 字段列表 from 表1 left join 表2 on 条件;
#查询的是左表所有数据以及其交集部分.左边的表为主表,主表记录全部显示,辅表没办法一一对应上的就通过null补全.
select * from dep left join emp on dep.id = emp.dep_id;
②右外连接(优先显示右表全部记录)
语法 select 字段列表 from 表1 right join 表2 on 条件;
select * from dep right join emp on dep.id = emp.dep_id;
③全外连接(显示左右两个表全部记录)
#mysql不支持全外连接full join,可以通过以下方式间接实现全外连接
select * from dep left join emp on dep.id = emp.dep_id union
select * from dep right join emp on dep.id = emp.dep_id;
4.子查询(一个查询结果作为另外一个查询的条件)
概念:查询中嵌套查询,称嵌套查询或子查询
#内层查询语句的查询结果,可以为外层查询语句提供查询条件。
#子查询中可以包含:in,not in,any,all,exists和not exists等关键字
#还可以包含比较运算符:= 、 !=、> 、<等
select name from emp where dep_id = (select id from dep where name = '技术');
①带in关键字的查询
select name from emp where dep_id in (select id from dep where name = '技术');
#查看技术部员工姓名
select name from dep where id not in(select distinct dep_id from emp)
#查看不足1人的部门名
②带比较运算符的子查询
select name,age from emp where age > (select avg(age) from emp);
#查询大于所有人平均年龄的员工名与年龄
③带exists关键字的子查询
EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录。而是返回一个真假值。True或False
当返回True时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询。还可以写not exists,和exists的效果就是反的
select * from emp where exists(select id from dep where id = 200);