day05 连表查询与子查询
day05 连表查询与子查询
昨日内容回顾
表关系之一对一
换位思考之后得出两边都是不可以
要么是没有关系,要么是一对一
一对一的表关系外键虽然建在哪个都可以,但是建议建在查询频率多的表上
# 外键其实是强耦合,有时候表热别多的时候并不一定建外键,而是用过代码建立逻辑意义上的关系
操作表的SQL语句补充
1、修改表名称
rename table m1 to m2;
rename table m1 to m2,m3 to m4;
2、添加表字段
alter table m1 add age int;
3、删除字段名
alter table m1 drop age;
4、修改字段名和字段类型
alter table m1 modify age int;
alter table change age age1 int;
复制表
# SQL语句的查询结果其实也可以看成一张虚拟表
create table m1 select * from user;
create table m1 select * from user where 1=2;
create teble m1 like user;
表查询关键字
select
from
where
group by
reder by
having
distinct
聚合函数
max
min
sum
count
avg
补充知识
1、起别名
as语法:给字段和表起名称
2、group_concat:拼接分组之后的字段
3、concat:拼接分组之前的字段
4、concat_ws:多个连接符相同情况下
今日内容概要
表查询关键字补充
多表查询两种方法
可视化软件
多表查询练习题
今日内容
表查询关键字补充
1、limlt:分页
# 只跟一个数字
select * from emp limit 5; # 从头开始展示n行数据
# 只跟两行数字
select * from emp limit 5,5; # 第一个是起始位置,第二个是展示n行数据
案例:求薪资最高的员工所有数据
1.先按照薪资降序排序
2.在使用limit限制取一行
select * from emp order by salary desc limit 1;
2、regexp:正则表达式
select * from emp where name regexp '^j.*(n|y)$'
3、exists:是否存在
EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录,
而是返回一个真假值,True或False。
当返回True时,外层查询语句将进行查询
当返回值为False时,外层查询语句不进行查询。
select * from emp # 存在执行这个
where exists
(select id from emp where id > 3); # 先验证这条数据是否存,存在执行上边
select * from emp
where exists
(select id from emp where id > 250); # 验证不存在,报错
多表查询两种方法之准备
# 数据准备
#建表
create table dep(
id int primary key auto_increment,
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
('jason','male',18,200),
('tony','female',48,201),
('kevin','male',18,201),
('nick','male',28,202),
('owen','male',18,203),
('jerry','female',18,204);
多表查询方法之连表操作
# 连表操作
先将查询涉及到的表拼接成一张大表 之后基于单表查询
# 笛卡尔积:把所有的数据全部对一遍
select * from emp,dep; # 错误
select * from emp,dep where dep_id=id; # 表意不明确
select emp.name,dep.name from emp,dep where emp.dep_id=dep.id; # 加上哪个表的字段名
"""
涉及到多表操作的时候 为了避免表字段重复
需要在字段名的前面加上表名限制
"""
# 上述操作并不是合理的连表操作,因为效率太差
连表操作关键字:
1、inner join 内连接:只连接两表中都存在(有对应关系)的数据
select emp.name,dep.name from emp inner join dep on emp.dep_id=dep.id;
2、left join 左连接:以左表为基准展示左表所有的数据没有对应则NULL填充
select * from emp left join dep on emp.dep_id = dep.id;
3、right join 右连接:以右表为基准展示右表所有的数据没有对应则NULL填充
select * from emp right join dep on emp.dep_id = dep.id;
4、union 全连接:展示左右两表中所有的数据没有对应则NULL填充
select * from emp left join dep on emp.dep_id = dep.id
union
select * from emp right join dep on emp.dep_id = dep.id;
多表查询方法之子查询
# 子查询:其实就是分步操作
将一张表的查询结果当做另外一条SQL语句的查询条件
1、查询部门是技术或者人力资源的员工信息
(1)、先查询技术和人力资源的部门标号
select id from dep where name in ('技术','人力资源');
(2)、根据部门编号去员工表中筛选对应的员工数据
select * from emp where dep_id in (200,201);
# (3)、将SQL语句括号起来即可充当查询条件
select * from emp where dep_id in (select id from dep where name in ('技术','人力资源'));
可视化软件
为了提高开发的效率 但是不能太过于依赖该软件
其实这些软件的底层还是执行的SQL语句来操作数据库的
该软件是收费的 但是有很多破解版本 自我百度下载即可(正式版只能使用14天)
1.链接数据库
2.创建数据库
3.创建表
4.创建数据
5.创建外键
6.逆向数据库到模型
7.转储SQL文件
多表查询练习题
练习题
1、查询所有的课程的名称以及对应的任课老师姓名
2、查询学生表中男女生各有多少人
3、查询物理成绩等于100的学生的姓名
4、查询平均成绩大于八十分的同学的姓名和平均成绩
5、查询所有学生的学号,姓名,选课数,总成绩
6、 查询姓李老师的个数
7、 查询没有报李平老师课的学生姓名
8、 查询物理课程比生物课程高的学生的学号
9、 查询没有同时选修物理课程和体育课程的学生姓名
10、查询挂科超过两门(包括两门)的学生姓名和班级
、查询选修了所有课程的学生姓名
12、查询李平老师教的课程的所有成绩记录
13、查询全部学生都选修了的课程号和课程名
14、查询每门课程被选修的次数
15、查询之选修了一门课程的学生姓名和学号
16、查询所有学生考出的成绩并按从高到低排序(成绩去重)
17、查询平均成绩大于85的学生姓名和平均成绩
18、查询生物成绩不及格的学生姓名和对应生物分数
19、查询在所有选修了李平老师课程的学生中,这些课程(李平老师的课程,不是所有课程)平均成绩最高的学生姓名
20、查询每门课程成绩最好的前两名学生姓名
21、查询不同课程但成绩相同的学号,课程号,成绩
22、查询没学过“叶平”老师课程的学生姓名以及选修的课程名称;
23、查询所有选修了学号为1的同学选修过的一门或者多门课程的同学学号和姓名;
24、任课最多的老师中学生单科成绩最高的学生姓名
习题1:查询所有的课程的名称以及对应的任课老师姓名
# 解题思路:大象放冰箱
1.先写思路在写SQL语句
2.查看本题需要用到哪些表。
3.一步步查询,不可一步就完成
1、查询所有的课程的名称以及对应的任课老师姓名
# 1.本题需要用到course、teacher两张表
# 2.查询结果肯定来源于这两张表,得出结论先连表:inner join
步骤1:先连表查询
select * from course inner join teacher on course.teacher_id=teacher.tid;
步骤2:只查询需要的字段:course.cname、teacher.teacher,再美化一下。
select course.cname,teacher.tname from course inner join teacher on course.teacher_id=teacher.tid;
习题2:查询平均成绩大于八十分的同学的姓名和平均成绩
2、查询平均成绩大于八十分的同学的姓名和平均成绩
# 1.本题需要用到score、student两张表
# 2.解题思路:先查询平均成绩大于八十分的同学id,然后在连表
步骤1: 按照学生id分组,之后求每个学生的平均成绩
select student_id,avg(num) as avg_num from score group by student_id;
步骤2:在使用having过滤出平均成绩大于80分的学生id # 给聚合函数起一个别名,要不然多表查询拿不到数据
select student_id,avg(num) as avg_num from score group by student_id having avg(num)>80;
步骤3:用子列表把查询到的表跟student表,按照学生id拼接到一起
select student.sname,m1.avg_num from student inner join (select student_id,avg(num) as avg_num from score group by student_id having avg(num)>80) as m1 on student.sid=m1.student_id;
步骤4:美化SQL语句
SELECT
student.sname,
m1.avg_num
FROM
student
INNER JOIN ( SELECT student_id, avg( num ) AS avg_num FROM score GROUP BY student_id HAVING avg( num )> 80 ) AS m1 ON student.sid = m1.student_id;
习题3:查询没有报李平老师课的学生姓名
# 本题需要用到的表:teacher、course、score、student
# 结题思路:
1、先查询李平老师带哪几门课程,
2、然后在去成绩表中查询上了李平老师课程的学生id
3、利用not in 查询出没有选李平老师课程的学生姓名
# 1.先查询李平老师带的几门课程、涉及的表有teacher、course
select course.cid from teacher inner join course on teacher.tid=course.teacher_id where teacher.tname in ('李平老师')
# 2.在course中查询上了李平老师课程的学生id
select distinct score.student_id from score inner join (select course.cid from teacher inner join course on teacher.tid=course.teacher_id where teacher.tname in ('李平老师')) as m1 on score.course_id=m1.cid
# 3.再用student表查询没报李平老师课程的id
select sname from student where sid not in (select distinct score.student_id from score inner join (select course.cid,teacher.tname from teacher inner join course on teacher.tid=course.teacher_id where teacher.tname in ('李平老师')) as m1 on score.course_id=m1.cid)
习题4:查询没有同时选修物理课程和体育课程的学生姓名
# 查询没有同时选修物理课程和体育课程的学生姓名
# 1.先查询出选修物理课程和体育课程的课程
select cid from course where cname in ('物理','体育')
# 2.用in查询出选择物理课程和体育课程的学生id,在通过分组过滤筛选出同时选修两门课程的学生id
select student_id from score where score.course_id in (select cid from course where cname in ('物理','体育')) group by student_id having count(course_id)=2
# 3.通过学生id查询学生姓名,在通过not in找出没有同时选修物理课程和体育课程的学生姓名
select sname from student where student.sid not in (select student_id from score where score.course_id in (select cid from course where cname in ('物理','体育')) group by student_id having count(course_id)=2) # count(course_id)=2 同时选修两门课程
习题1:查询所有的课程的名称以及对应的任课老师姓名
# 查询所有的课程的名称以及对应的任课老师姓名
# 1.用到course、teacher表
select teacher.tname,course.cname from course inner join teacher on course.teacher_id=teacher.tid;
# 2.美化代码
SELECT
teacher.tname,
course.cname
FROM
course
INNER JOIN teacher ON course.teacher_id = teacher.tid;
习题2:查询学生表中男女生各有多少人
# 查询学生表中男女生各有多少人
# 1.用到的表student
select gender as '性别',count(gender) as '人数' from student group by gender
# 2.美化代码
SELECT
gender AS '性别',
count( gender ) AS '人数'
FROM
student
GROUP BY
gender;
习题3:查询物理成绩等于100的学生的姓名
# 查询物理成绩等于100的学生的姓名
# 1.用到的表course、score、student
select cid from course where cid = '2'
# 2.查询score选修了物理的学生id
select student_id from score where course_id in (select cid from course where cid = '2') and num=100
# 3.去student表中查询学生姓名
select sname from student where sid in (select student_id from score where course_id in (select cid from course where cid = '2') and num=100)
习题4:查询平均成绩大于八十分的同学的姓名和平均成绩
4、查询平均成绩大于八十分的同学的姓名和平均成绩
# 1.本题需要用到score、student两张表
# 2.解题思路:先查询平均成绩大于八十分的同学id,然后在连表
步骤1: 按照学生id分组,之后求每个学生的平均成绩
select student_id,avg(num) as avg_num from score group by student_id;
步骤2:在使用having过滤出平均成绩大于80分的学生id # 给聚合函数起一个别名,要不然多表查询拿不到数据
select student_id,avg(num) as avg_num from score group by student_id having avg(num)>80;
步骤3:用子列表把查询到的表跟student表,按照学生id拼接到一起
select student.sname,m1.avg_num from student inner join (select student_id,avg(num) as avg_num from score group by student_id having avg(num)>80) as m1 on student.sid=m1.student_id;
步骤4:美化SQL语句
SELECT
student.sname,
m1.avg_num
FROM
student
INNER JOIN ( SELECT student_id, avg( num ) AS avg_num FROM score GROUP BY student_id HAVING avg( num )> 80 ) AS m1 ON student.sid = m1.student_id;
习题5:查询所有学生的学号,姓名,选课数,总成绩
# 查询所有学生的学号,姓名,选课数,总成绩
# 用到的表student、score、course
# 1.找到学号、选修课数、总成绩
select student_id,count(course_id), sum(num) from score group by score.student_id;
# 2.找到学生姓名
select student.sid,student.sname from student;
# 3.找到所有信息
select sid,sname,m1.course_id,m1.sum_num from student inner join (select student_id,count(course_id) as course_id, sum(num) as sum_num from score group by score.student_id ) as m1 on student.sid=m1.student_id;
优化:
SELECT
sid,
sname,
m1.course_id,
m1.sum_num
FROM
student
INNER JOIN ( SELECT student_id, count( course_id ) AS course_id, sum( num ) AS sum_num FROM score GROUP BY score.student_id ) AS m1 ON student.sid = m1.student_id;
day05 连表查询与子查询的更多相关文章
- MS sql server 基础知识回顾(二)-表连接和子查询
五.表连接 当数据表中存在许多重复的冗余信息时,就要考虑将这些信息建在另一张新表中,在新表中为原表设置好外键,在进行数据查询的时候,就要使用到连接了,表连接就好像两根线,线的两端分别连接两张表的不同字 ...
- MySQL多表查询之外键、表连接、子查询、索引
MySQL多表查询之外键.表连接.子查询.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为 ...
- MySQL开发——【联合查询、多表连接、子查询】
联合查询 所谓的联合查询就是将满足条件的结果进行拼接在同一张表中. 基本语法: select */字段 from 数据表1 union [all | distinct] select */字段 fro ...
- MySQL之多表查询一 介绍 二 多表连接查询 三 符合条件连接查询 四 子查询 五 综合练习
MySQL之多表查询 阅读目录 一 介绍 二 多表连接查询 三 符合条件连接查询 四 子查询 五 综合练习 一 介绍 本节主题 多表连接查询 复合条件连接查询 子查询 首先说一下,我们写项目一般都会建 ...
- mysql查询语句 和 多表关联查询 以及 子查询
原文地址: http://blog.csdn.net/github_37767025/article/details/67636061 1.查询一张表: select * from 表名: 2.查询指 ...
- ORACLE 多表连接与子查询
Oracle表连接 SQL/Oracle使用表连接从多个表中查询数据 语法格式: select 字段列表from table1,table2where table1.column1=table2.co ...
- Server Sql 多表查询、子查询和分页
一.多表查询:根据特定的连接条件从不同的表中获取所需的数据 多表查询语法: SELECT table1.column, table2.column FROM table1, table2 WHERE ...
- ylb:SQL 表的高级查询-多表连接和子查询
ylbtech-SQL Server: SQL Server-表的高级查询-多表连接和子查询 SQL Server 表的高级查询-多表连接和子查询. 1,ylb:表的高级查询-多表连接和子查询 返回顶 ...
- oracle多表关联查询和子查询
oracle多表关联查询和子查询 一.多表关联查询 例子: SQL> create table student1 ( sid ), sname ), sage )); Table created ...
随机推荐
- Spring Cloud Gateway夺命连环10问?
大家好,我是不才陈某~ 最近有很多小伙伴私信我催更 <Spring Cloud 进阶>,陈某也总结了一下,最终原因就是陈某之前力求一篇文章将一个组件重要知识点讲透,这样导致了文章篇幅很长, ...
- 旋转数组的最小数字 牛客网 剑指Offer
旋转数组的最小数字 牛客网 剑指Offer 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4, ...
- si macro macro
获取 buf 里的 symbol cbuf = BufListCount() msg(cbuf) ibuf = 0 while (ibuf < cbuf) { hbuf = BufListIte ...
- hdu 1198 Farm Irrigation(并查集)
题意: Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a ...
- 攻防环境配置大全(iss/apache/nginx/tomcat/jboss/weblogic)
一.IIS/apache/nginx/tomcat 介绍 1.asp aspx 只能在微软系统的iis中间件运行 [asp+IIS+access(扩展名为mdb)].aspx+mssql+iis结合, ...
- Ambari 2.4 在 CentOS 7.4 因 TLS_1.2 协商内部错误导致注册失败
问题背景 业务准备在天翼云上搭建一套线上环境,VM 操作系统版本为 CentOS Linux release 7.4.1708,但是在 ambari Web 管理页面上部署hadoop节点主机的时候, ...
- Maven settings配置阿里镜像
一般只用配置三个地方 maven仓库路径 镜像 默认JDK版本 <?xml version="1.0" encoding="UTF-8"?> < ...
- Python推导式详解,带你写出比较精简酷炫的代码
Python推导式详解,带你写出比较精简酷炫的代码 前言 1.推导式分类与用法 1.1 列表推导 1.2 集合推导 1.3 字典推导 1.4 元组推导?不存在的 2.推导式的性能 2.1 列表推导式与 ...
- JMeter接口自动化发包与示例
JMeter接口自动化发包与示例 近期需要完成对于接口的测试,于是了解并简单做了个测试示例,看了看这款江湖上声名远播的强大的软件-Jmeter靠不靠谱. 官网:https://jmeter.apach ...
- 3D 穿梭效果?使用 UWP 也能搞定
昨天 ChokCoco 大佬搞了个 3D 穿梭效果出来,具体可见这里: 3D 穿梭效果?使用 CSS 轻松搞定 这个效果太神奇了,他还问我能不能用 WPF 搞出来,因为我完全没用过 WPF 的 3D, ...