一.外键 变种:
三种关系: 多对一 站在左表的角度: (1)一个员工 能不能在 多个部门? 不成立 (2)多个员工 能不能在 一个部门? 成立 只要有一个条件成立:多 对 一或者是1对多 如果两个条件都成立: 多对多 要创建第三张表进行关联 多对多 双向的多对一一对一
示例(一对一)
#两张表: 用户表 (user)和 博客表(blog)
# 创建用户表 create table user( id int primary key auto_increment, name varchar(20) ); # 创建博客表 create table blog( id int primary key auto_increment, url varchar(100), user_id int unique, on update cascade ); #插入用户表中的记录 insert into user(name) values ('alex'), ('wusir'), ('egon'), ; # 插入博客表的记录 insert into blog(url,user_id) values ('http://www.cnblog/alex',1), ('http://www.cnblog/wusir',2), ('http://www.cnblog/egon',3),
单表查询
一.语法:select 字段 from 表名 where 条件 group by field having 筛选 order by field limit 限制条数二.关键字的执行优先级 from where group by having select distinct order by limit说明:1.找到表 from2.拿着where指定的约束条件,去表中取出一条条记录3.将取出的一条条记录进行分组group by,如果没有group by ,则整体作为一组4.将分组的结果进行having过滤5.执行select6.去重7.将结果按条件排序:order by 8.限制结果的显示条数create table employee(id int primary key 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),('xiaomage','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.where 约束: * 比较运算符:> < >= <= <> !=; * between 80 and 100 ; *in(80, 90 ,100) *like "xiaomage":pattern 可以是% 或 _ . % 任意多字符,_表示一个字符; * 逻辑运算符:有多个条件可以直接使用逻辑运算符 and or not;2.group by 分组查询:(1) 首先明确一点: 分组发生在where 之后,即分组是基于where之后得到的记录而进行的;(2) 分组指的是:将所有记录按照某个相同字段进行归类,比如针对员工信息表的职位分组,或者按照性别进行分组等.(3)为何要分组? 取每个部门的最高工资; 取每个部门的员工数; 取男人数和女人数;小窍门:"每这个字后面的字段,就是我们分组的依据.(4).大前提: 可以按照任意字段分组,但是分组完毕后,比如group by post ,只能查看post字段,如果想查看组内信息,需要借助聚合函数. select post from employee group by post; (只能看post字段) 什么是聚合函数? 聚合函数聚合的是组的内容,若没有分组,则默认一组;SQL中提供的聚合函数可以用来统计、求和、求最值等等。 –COUNT():统计行数量 count(1) –SUM():获取单个列的合计值 –AVG():计算某个列的平均值 –MAX():计算列的最大值 –MIN():计算列的最小值 示例: 每个部门有多少个员工 select post,count(id) from employee group by post; 每个部门的最高薪水 select post,max(salary) from employee group by post; 每个部门的最低薪水 select post,min(salary) from employee group by post; 每个部门的平均薪水 select post,avg(salary) from employee group by post; 每个部门的所有薪水 select post,sum(salary) from employee group by post; 注意: select * from employee group by post;是以post字段查询了组中的第一条数据如果想分组,则必须要设置全局的sql的模式为ONLY_FULL_GROUP_BY 设置成功后,一定要退出,然后重新登录方可生效示例:set global sql_mode='ONLY_FULL_GROUP_BY';补充: 查看MySQL 5.7默认的sql_mode如下: 命令: select @@global.sql_mode;3.having 过滤(1)having发生在分组group by 之后,因而 having中可以使用分组的字段,无法直接取到其他字段,可以使用聚合函数(2)where和having的区别 where 发生在分组group by 之前,因而where中可以有任意字段,但是绝对不能使用聚合函数;(3)函数group_concat() 必须使用group by 才能使用此函数,4.order by 查询顺序
按单列排序: SELECT * FROM employee ORDER BY age; SELECT * FROM employee ORDER BY age ASC; (升序) SELECT * FROM employee ORDER BY age DESC; (降续) 按多列排序: 先按照age升序排序,如果年纪相同,则按照id降序 select * from employee order by age ASC,id DESC;5.limit 限制查询的记录数 示例: select * from employee order by salary DESC limit 3;(默认初识位置为0) SELECT * FROM employee ORDER BY salary DESC limit 0,5;(从第0开始,即先查询出第一条,然后包含这一条在内往后查5条) SELECT * FROM employee ORDER BY salary DESC limit 5,5;(从第5开始,即先查询出第6条,然后包含这一条在内往后查5条) 多表查询 一.多表连接查询外链接语法 语法: select 字段列表 from 表1 inner/left/right join 表2 on 表1.字段 = 表2.字段;1.交叉连接:不适用任何匹配条件,生成笛卡尔积 命令: select * from employee,department;2.内连接:只连接匹配的行 找两张表共有的部分,相当于利用条件从笛卡尔积结果中筛选出了匹配的结果 命令: select employee.id,employee.name,employee.age,employee.sex,department.name from employee inner join department on employee.dep_id=department.id; 以上命令相当于: select employee.id,employee.name,employee.age,employee.sex,department.name from employee,department where employee.dep_id=department.id;3.外链接之左连接:优先显示左表全部记录 本质就是:在内连接的基础上增加左边有,右边没有的结果 命令: select employee.id,employee.name,department.name as depart_name from employee left join department on employee.dep_id=department.id;4.外链接之右连接:优先显示右表全部记录 本质就是:在内连接的基础上增加右边有,左边没有的结果 命令; select employee.id,employee.name,department.name as depart_name from employee right join department on employee.dep_id=department.id;5.全外链接:显示左右两个表全部记录 在内连接的基础上增加左边有右边没有的和右边有左边没有的结果注意:mysql不支持全外链接 full join;强调:mysql可以使用此种方式间接实现全外链接命令: select * from employee left join department on employee.dep_id = department.id union all select * from employee right join department on employee.dep_id = department.id; select * from employee left join department on employee.dep_id = department.id union (union会去掉相同的记录) select * from employee right join department on employee.dep_id = department.id二.符合条件连接查询 示例1:以内连接的方式查询employee和department表,并且employee表中的age字段值必须大于25, 即找出年龄大于25岁的员工以及员工所在的部门 命令: select employee.name,department.name from employee inner join department on employee.dep_id = department.id where age > 25; 示例2:以内连接的方式查询employee和department表,并且以age字段的升序方式显示。 select employee.id,employee.name,employee.age,department.name from employee,department where employee.dep_id = department.id and age > 25 order by age asc;三.子查询 子查询是将一个查询语句嵌套在另一个查询语句中. 内层查询语句的查询结果,可以为外层查询语句提供查询条件. 子查询中可以包含:in not any all exists 和 not exists 还可以包含比较运算符:= != < >;1.带in关键字的子查询 查询平均年龄在25岁以上的部门名 select id,name from department where id in (select dep_id from employee group by dep_id having avg(age) > 25); 查看技术部员工姓名 select name from employee where dep_id in (select id from department where name='技术'); 查看不足1人的部门名 select name from department where id not in (select dep_id from employee group by dep_id);2.带比较运算符的子查询比较运算:= != < <= > >= <>查询大于所有人平均年龄的员工名与年龄命令: select name,age from employee where age >(select avg(age)from employee);查询大于部门内平均年龄的员工名、年龄命令: 说明: 第一层找最终要的内容 查询员工名字和年龄 第二层 判断条件 大于部门内平均年龄 第三层部门内平均年龄 第四层按部门分组获取部门及平均年龄 第五层 员工age和部门内平均年龄比较 第六层将员工表年龄姓名虚拟表与所在部门及部门平均年龄的虚拟表组合成一张虚拟表, 第七层判断条件 select t1.name,t1.age from employee as t1 inner join (select dep_id avg(age) as avg_age from employee group by dep_id) as t2 on t1.dep_id =t2.dep_id where t1.age>t2.avg_age;3.带exists关键字的子查询 EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录。而是返回一个真假值。True或False 当返回True时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询 示例: select * from employee where exists (select id from department where id=200);回顾:
完整型约束:
作用:保证数据的完整型和一致性
- not null 和 default - unique 唯一的 1.单列唯一 2.多列唯一 3.联合唯一 - 主键 primary key(索引) 一个表中只有一个主键,可以有联合主键 1.单列主键 2.多列主键(有问题) 不允许 2.联合主键 primary key(id,name,age) 作用: 唯一标识 查询优化 - 外键 foreign key 连接 从表(关联表)和主表(被关联表)的关系 (1)先创建主表 (2)再去创建从表
存储引擎
innodb myisam memory blackhole 数据类型 - 整型 tinyint int bigint - 小数 float double decimale - 字符 char(定长 存储的速度快 浪费空间 char_length() length() sql_mode) varchar(变长 节省空间 存储速度慢) - 日期 year date time datetime - 枚举 enum - 集合 set 默认有符号的 signed 无符号的 unsigned 用零填充 zerofill 验证int类型的显示宽度