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 连表查询与子查询的更多相关文章

  1. MS sql server 基础知识回顾(二)-表连接和子查询

    五.表连接 当数据表中存在许多重复的冗余信息时,就要考虑将这些信息建在另一张新表中,在新表中为原表设置好外键,在进行数据查询的时候,就要使用到连接了,表连接就好像两根线,线的两端分别连接两张表的不同字 ...

  2. MySQL多表查询之外键、表连接、子查询、索引

    MySQL多表查询之外键.表连接.子查询.索引 一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为 ...

  3. MySQL开发——【联合查询、多表连接、子查询】

    联合查询 所谓的联合查询就是将满足条件的结果进行拼接在同一张表中. 基本语法: select */字段 from 数据表1 union [all | distinct] select */字段 fro ...

  4. MySQL之多表查询一 介绍 二 多表连接查询 三 符合条件连接查询 四 子查询 五 综合练习

    MySQL之多表查询 阅读目录 一 介绍 二 多表连接查询 三 符合条件连接查询 四 子查询 五 综合练习 一 介绍 本节主题 多表连接查询 复合条件连接查询 子查询 首先说一下,我们写项目一般都会建 ...

  5. mysql查询语句 和 多表关联查询 以及 子查询

    原文地址: http://blog.csdn.net/github_37767025/article/details/67636061 1.查询一张表: select * from 表名: 2.查询指 ...

  6. ORACLE 多表连接与子查询

    Oracle表连接 SQL/Oracle使用表连接从多个表中查询数据 语法格式: select 字段列表from table1,table2where table1.column1=table2.co ...

  7. Server Sql 多表查询、子查询和分页

    一.多表查询:根据特定的连接条件从不同的表中获取所需的数据 多表查询语法: SELECT table1.column, table2.column FROM table1, table2 WHERE ...

  8. ylb:SQL 表的高级查询-多表连接和子查询

    ylbtech-SQL Server: SQL Server-表的高级查询-多表连接和子查询 SQL Server 表的高级查询-多表连接和子查询. 1,ylb:表的高级查询-多表连接和子查询 返回顶 ...

  9. oracle多表关联查询和子查询

    oracle多表关联查询和子查询 一.多表关联查询 例子: SQL> create table student1 ( sid ), sname ), sage )); Table created ...

随机推荐

  1. exec系统调用 && 进程的加载过程

    exec系统调用会从指定的文件中读取并加载指令,并替代当前调用进程的指令.从某种程度上来说,这样相当于丢弃了调用进程的内存,并开始执行新加载的指令. exec系统调用会保留当前的文件描述符表单.所以任 ...

  2. Linux&C———进程间通信

    管道和有名管道 消息队列 共享内存 信号 套接字 由于进程之间的并不会像线程那样共享地址空间和数据空间,所以进程之间就必须有自己特有的通信方式,这篇博客主要介绍自己了解到的几种进程之间的通信方式,内容 ...

  3. ES6模块化引入

    //a.js 导出的关键字 export export let str = "laowang"; export function add(a,b){ return a + b ; ...

  4. 经过4次优化我把python代码耗时减少95%

    背景交代 团队做大学英语四六级考试相关服务.业务中有一个care服务,购买了care服务考试不过可以全额退款,不过有一个前提是要完成care服务的任务,比如坚持背单词N天,完成指定的试卷. 在这个背景 ...

  5. Spring Ioc 容器初始化过程

    IOC 是如何工作的? 通过 ApplicationContext 创建 Spring 容器,容器读取配置文件 "/beans.xml" 并管理定义的 Bean 实例对象.   通 ...

  6. SpringCloud微服务实战——搭建企业级开发框架(十六):集成Sentinel高可用流量管理框架【自定义返回消息】

    Sentinel限流之后,默认的响应消息为Blocked by Sentinel (flow limiting),对于系统整体功能提示来说并不统一,参考我们前面设置的统一响应及异常处理方式,返回相同的 ...

  7. 本机不安装Oracle客户端,使用instantclient_11_2和PLSQL Developer连接Oracle远程数据库步骤

     前言:由于Orcale客户端,占用空间太大,我们选择安装installclient\PLSQL客户端对orcale进行数据库连接. 安装要求.installClient要与PLSQL的安装位数一致, ...

  8. [cf1349D]Slime and Biscuits

    枚举最终的获得所有饼干的人$i$(以下简称"获胜者"),对于$i$获胜的情况,令其贡献为游戏轮数,否则其贡献为0,记$F_{i}$为期望贡献(即所有情况概率*贡献之和),答案即为$ ...

  9. [nowcoder5666B]Infinite Tree

    首先考虑由$1!,2!,...,n!$所构成的虚树的一些性质: 1.每一个子树内所包含的阶乘的节点都是一个连续的区间(证明:对于子树k,如果存在$x!$和$y!$,即说明$x!$和$y!$的前$\de ...

  10. Windows快捷键及cmd打开方式

    Windows快捷键 win+e 打开我的电脑 win+r 打开运行 ctrl+z 撤销 shift+del 彻底删除 alt+F4 关闭窗口 ctrl+c 复制 ctrl+a 全选 ctrl+x 剪 ...