今日内容: 查询语句: 1.完整的查询语句 2.一堆关键字 查询的语句 3.单表查询 4.对表查询 5.子查询 一. 一对一关系的补充:(外键 (foreign key)应该增加从表) 客户表,学员表 一个客户只对应一个客户 >>>一对一>>外键(两个表有关系就有外键) 创建客户表: create table customer(id int primaary key auto_increment,name char(10).phone char(11),sex char(3)) 创建学生表: create table stydent(id int primaary key auto_increment,name char(10),sex char(3),class char(10),c_id int , foreign key(c_id) references customer(id) on update cascade on delete cascade ) 二. 复制表: 1. create table copy_table select * from t1 ; 完全复制(结构加数据) 2. create table copy_table select * from t1 where 1>10; 拷贝结构 (后面加一个不成立条件 ); 共同点; 主键(索引) 描述 不能拷贝(自增) 三. 记录的详细操作 1.增; insert [into] 表名[字段名] values|value(字段值.......) into 可以省略 [字段名] 可选 : 选了 后面的值 必须与 写的字段匹配 不写 后面的值 必须和表的结构完全匹配 value 插入一条记录 values 插入多条记录 2.删: delete from 表名 [where 条件] where 可选: 有 修改满足条件的记录 没有 就全部修改 如果需要全部删除 使用:truncate table 表名: 原因:delete 是逐行删除 效率低 删除的行会保留行数 3.改: update 表名 set 字段名 = 新的值[,字段n=新的n] [where 条件] 可以同时修改 多个字段 用逗号隔开 注意最后一个字段不能隔开 where 可选: 有 修改满足条件的记录 没有 就全部修改 4.查: 完整的查询语句: select [distinct] {*|字段名,字段名|聚合函数| 表达式} from 表名 [ where 条件 group by 字段名 having 条件 order by 字段名 limit 显示的条数] 注意:关键字的顺序比必须与上述语法一致 执行的顺序:from >>> where (逐行的去读) >> 1. * 表示所有列 2.distinct 表示去重 (只去除完全相同的记录) 可以手动指定要显示的列,从而去重 3.表达式:加减乘除 ][ def select(); from(): 打开文件 where() : 读取每一行并判断是否满足条件(从硬盘读取全部的数据) group by (): 对数据进行分组 >> 方便对数据进行操作 having(): 在分组之后进行过滤 having 不单独出现 仅用于分组之后进行过滤 distinct(): 去重 order by(): 用于对筛选后的数据进行排序 limit () : 限制显示的条数 最后根据select后制定的字段来显示排序 练习: 1.查询所有人的成绩 select name,English+math as 总分 from stu; select name,English+10 as 英语 from stu; 2. 需要在字段的数据前面加上字段名: name:赵云 English:90 math:19 需要字符串拼接函数:concat(字符串) select concat("name",name), concat("english",english), concat("math",math) from stu 3. case ** select (case when english +math <150 then concat(name,"shit") when english +math >=150 then concat(name,"nice") end) from stu 四.关键字 1. where : 从硬盘上读取数据时的一个过滤条件 1. < ,> <= ,>= != 2. like :(%:0个或多个 _:一个) 模糊查询 "李%":后有李的 "%李% ":只要有李的 3. between x and y : 区间 4. in (集合) or where 的筛选过程: 在没有索引的条件下 挨个比较 2. group by : 用于给数据分组(每字) 1. 在生活中是为了好管理 2. 在数据库中是为了方便统计 使用: 1. 创建数据; 2 查询: select * from emp group by dept >>没意义 但还是会显示 : 解决问题 set global sql_mode="STRICT_TRANS_TABLES,ONLY_FULL_GROUP_BY" 两种情况: 1. sql_mode 没有设置 ONLY_FULL_GROUP_BY 显示每个组的第一条信息 没有意义 新版中 自带 2. sql_mode 有设置 ONLY_FULL_GROUP_BY 直接报错 原因: * 表示的是所有的字段都要显示 ,但是分组后记录的细节被隐藏 这就意味着:出现在group by 后面的字段才能被显示 (不能全查 不能用*) 分组是为了 统计数据 >>> 用到聚合函数 3.聚合函数: 将一堆数据经过计算 得到一个数据 sum() 求和 : select sum(salary) from emp avg() 求平均值 : max()/min() 最大值/最小值 count() 个数 4. gropr_concat:拼接 没啥意义 select dept,gropr_concat(name) from emp group by dept 需求 : 1. 求出每个部门的最高工资 select dept(部门名字),max(salary) from empty group by dept 2. 求每个部门中每个岗位的平均工资 select dept ,job ,avg(salary) from emp group by dept ,job 3.查询每个部门有几个人 select dept,count(*) from emp group by dept; 4. 计算每个部门的平均工资: select dept ,avg(salary) from emp group by dept 5. 查询平均工资大于5000的部门 select avg(salary) from emp where avg(salary) > 500 group by ??报错 where 语句后面 不能使用聚合函数 不能使用筛选后的数据 3. hanving:对分组后的数据进行筛选|过滤 不能单独存在 都是和group by 与where 的区别: 相同点: 都用于过滤数据 不同点: 1. where 是最先执行的 用于读取硬盘数据 having 要等到数据读取完毕之后 才能进行过滤 比where晚 2. where 中不能是使用聚合函数 having 可以 1. 查询平均工资大于5000的部门 select dept,avg(salary) from emp group by dept having avg(salary) > 5000; 2. 查询工资最高的人姓名和他的工资 >>>需要用到子查询 4. order by :用于对记录进行排序(默认为升序) ********* desc为降序 asc 为升序 需求 1. 按工资的从低到高的顺序排 显示所有的员工 select * from order by salary 2. 每个部门的员工 按照工资降序排序(有问题) select name,dept,salary, from emp group by name,dept,salary order by salary desc; 3. 按照每个部门的平均工资排序 select dept,avg(salary) from emp group by dept order by avg(salary) desc; 5. limit :用于限制显示的条数 ****** limit[start,]count count (显示的条数) 需求: 1.看看表里的前三条数据 select * from emp limit 3; 2.表里的3-5条: select * from emp limit 2,3; 3. 查看工资最高的那个人的信息 select * from emp order by salary desc limit 1 ; limit 常用于 数据的分页展示 比如腾讯新闻的上拉加载新的一页 select * from emp limit 10; 第一页 页数 减一 乘以条数 得到起始位置 select * from emp limit 10,10; 第二页 select * from emp limit 20,10; 第三页 五:多表查询 在多个表中查询需要的数据 例如:在班级表 和 学生表 给你已给的班级名称 请查询所有的学员数据 先查询班级表 得到一个班级的id 在根据id去取学院查找学生信息 多查询的方式: 数据准备: 1. 笛卡尔积查询:用坐标中的一条记录 去链接另一张表的所有数据 select * from temp,dept 就像是把两张表的数据做了乘积 这将导致 会产生大量的无用重复的数据 我们要的效果是:员工表中的部门id 与 部门表中的id 相同 就拼接在一起 用 where 筛选出正确的数据 select * from emp,dept where emp.dept_id = dept.id on 关键字:用于多表查询的的条件限制 select * from emp,dept on emp.dept_id = dept.id 报错 因为 on只能用在专门多表查询的语句 2. 内连接查询: inner join 加 on select * from emp inner join dept on emp.dept_id= dept.id 3. 左外连接 需求: 查询所有的员工和他们所属的部门 left join 左边表的数据完全显示 右边表中的数据匹配上才显示 select * from emp left join dept on emp.dept_id= dept.id 4. 右边连接: right join 右边表的数据完全显示 左边表中的数据匹配上才显示 select * from emp right join dept on emp.dept_id= dept.id 5. 全外连接 full join mysql 不支持 Oracle支持 union : 合并查询(将第一个表的结果合并在一起,显示) 要求是结构必须相同 默认是去除重复的 union all : 合并 但是不去除重复 select * from emp union select * from dept; select * from emp left join dept on emp.dept_id= dept.id union select * from emp right join dept on emp.dept_id= dept.id 总结:多表连接 在书写时 按照填空的方式来书写 如果左边要全部显示 用left join 如果右边要全部显示 用 right join 全部显示: 将左连接的结果和右连接的结果 合并 三表连查: 数据准备: create table tec(id int,name char(10)); insert into tec value(1,"egon"); insert into tec value(2,"yyh"); create table stu(id int,name char(10)); insert into stu value(1,"大傻"); insert into stu value(2,"中傻"); insert into stu value(3,"小傻"); create table s_t(s_id int,t_id int); insert into s_t value(1,2); insert into s_t value(2,2); insert into s_t value(3,1); 需求 : 找出yyh 这个老师教过的学生的信息 思路: 第一件事: 到关系中 哪些老师教过哪些学生(学生的id) 形成一个临时表 第二件事:将上一步得到的临时表与学生表进行连接 第三件事:加上额外的筛选条件 select tec.name teacher stu.name student from tec inner join s_t on s_t.id=tec.id inner join stu on stu.id = s_id where tec.name ='yyh'; 六 .子查询:将上一次的查询结果 作为本次查询的原始数据 需求:查询出财务部工资最高的人的信息 1. 先查询财务部的最高工资 2. 拿着最该工资去找人 select max(salary) from emp grour by dept having dept ="财务部" select * from emp where salary= (select max(salary) from emp grour by dept having dept ="财务部") ******