ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

复杂SQL_01

2022-07-18 08:33:28  阅读:202  来源: 互联网

标签:01 join name 复杂 stu score SQL id select


目录

1.外联和内联★

left join/right join: 
特点: 主表所有的数据都显示,另外一张表中有匹配的数据有匹配的数据则显示,若无匹配的数据,该字段显示为null

inner join:
特点: 查询的所有数据是满足所有条件的数据,若没有满足所有条件的数据,则结果集为空

1658019469089

例题:

#查询所有公司人员的信息
SELECT u.*,r.name FROM USER U LEFT JOIN user_role r ON
u.id =r.user.id

2.sql语句的执行顺序★★

select distinct ... from ... (left/ right) join ... on ...
where ... group by ... having ... order by... limit ...

1. from  join	--> 产生虚拟表v1,产生的结果是笛卡尔积(m*n)
2. on  		    --> 根据产生的条件筛选, 产生虚拟表v2

3. left/ right join --> 若是外链接,将主表所有的数据进行补充到v2
4. where 		--> 根据查询条件,v2中进行筛选,产生虚拟表v3

5. group by		--> 对v3进行分组,产生虚拟表v4
6. having 		--> 对分组的结果v4 再次进行筛选产生虚拟表v5

7. select		--> 选择需要最终显示的字段,产生虚拟表v6
8. distinct 	--> 对显示的结果进行去重, 产生虚拟表v7
9. order by		--> 对结果某字段进行升序/降序排列
10. limit		--> 选择需要的数据进行分页展示

3.单标嵌套查询★★★★

考点:group by 能查到什么

可以查询到:

  • 分组后的cola(列A),
  • cola具有一对一关系的列
  • 相关的聚合函数,
  • 除此之外,其他字段都查询不到

错误示例

#获取班级的最后一名
select bj,min(score)
from stu_score 
group by bj         X

正确示例

正确的思路:

  1. 查询出每个班级的最低分
  2. 根据上述的查询结果,再次到stu_Score表中查询,查询某个班级最低分对应的学生是谁
# 获取班级的最后一名
# 解题思路: 
# 1.查询每个班级的最低分数
select bj,min(score) from stu_score group by bj 
# 2.查询最低分数对应的学生是谁
select ss.* from stu_scoure ss join 
(select bj,min(score) ms from stu_score group by bj)temp 
on temp.ms = ss.score and temp.bj = ss.bj

4.limit★★

between...and

# 表user,字段有:id(非自增,不连续),age,name,sex,addTime。求创建时间(addTime)在2020-
05-22至2020-06-17之间所有数据
select * from user
where addTime between '2020-05-22' and '2020-06-17'

limit 细节

第10条至第20条连续分页数据

# 基于表user,查出表中第10条至第20条连续分页数据的sql语句
select * from user limit 9,11

limit m,n    从索引m出开始筛选出n条数据 --实现分页
limit n      从第一条数据开始筛选前n条

5.ifnull()的使用和having★★

5.1 ifnull()的使用

  • 若结果为null,想替换为其他值,则可以使用数据库提供的函数 ifnull(exp1,exp2)
# 查询所有学生的学号,姓名,选课数,总成绩
select 
	s.sno,s.name,count(cno)'选课数',ifnull(sum(score),0)
from 
	student s 
left join 
	score sc on s.sno = sc.sno
group by 
	s.sno

5.2 查询没有学完所有课程的学生学号,姓名

# 查询选课数小于总课程数的学生
1.查询总课程数
select count(*) from course

2.统计每个学生的选课数
select count(cno)
from student s 
left join course1  c on s.sno = c.sno
group by s.sno 

3.合并
select s.sno,s.name
from student s 
left join course1  c on s.sno = c.sno
group by s.sno 
having count(cno) < (select count(*) from course)

6.多表联查

6.1 两表联查

# 查询所有学生的信息(学号,姓名,性别,班级名称)
select stu_no ,stu_name,stu_gender,class_name
from student s join class c on s.class_id = c.id

6.2 内外联交叉★★★

  • join on 和left join on
# 查询所有人(包括没有成绩的学生)的课程分数(学号,姓名,性别,班级名称,语文分数,数学分数)
select  stu_no,stu_name,stu_gender,class_name,chinese,math
from student s 
join class c on s.class_id = c.id
left join score o on o.sno = s.sno

- join...join...on...and
- join...on...left join... on

6.3 三表联查

# 查询语文分数比“张三”高的学生(学号,姓名,性别,班级名称,语文分 数)
# 解题思路
# 1.查询张三的分数
select chinese
from student s join score sc on sc.stu_id = s.id
WHERE stu_name = '张三'
# 2.查询比张三分数高的学生
select s.*,class_name,chinese
from student s
join score sc on sc.stu_id = s.id
join class c on s.class_id = c.id
where chinese > (select chinese
from student s join score sc on sc.stu_id = s.id
WHERE stu_name = '张三')

6.4 两表联查where

# 查询各科都合格(分数>=60)的学生(学号,姓名,语文分数,数学分数)
select stu_id,stu_name,chinese,math
from student s join score sc on sc.stu_id = s.id 
where chinese > 60 and math >60

6.5 两表联查having

#查询班级人数>=2的班级(班级编号,班级名称,人数)
select class_id ,class_name,count(s.stu_no) cou
from student s join class c on s.class_id = c.id
group by class_id
having cou>=2

7.思路转换 大小转换

#查询出每门课程都大于等于80分的学生信息 --> -最低分大于80
# step 1
select  s.*
from score
group by score
having min(score) >= 80
# step 2
select s.*
from score s
where name 
not in (select distinct name
        from score
        where score < 80)

8.嵌套删除

  • 有一张表student,包括字段id和name,请将表中name字段中重复记录删除,只保留重复数据中的id最大的那一条数据。
# 查询每个名字的最大id
select max(id) from student  group by name

delete from student 
where id not in (select max(id) from student  group by name)

9.多字段分组★

# 删除除了自动编号不同,其它都相同的学生冗余信息
delete from student2 
where id not in(
select min(id) from student 
group by stu_id,stu_name,course_id,course_name,score)

10.Case..When★★★★★

高频考试题 :

​ case when经常和聚合函数配合使用 -- 经常考察

注意点:case when 和sum()和count()使用时,用法不同(意义不同)

  • sum()配合使用,满足条件返回1,表示进行+1  else 0表示+0
  • count()配合使用,返回的值只要不是null,就进行一次计数,所以使用count()必须注意:若满足条件想进行一次计数,不满足条件不计数,应写成:
count(case when ....then 1 else null end)  或 
count(case when ...then 1 end) 没有else,表示不满足条件,返回null
select match_date'比赛日期',
sum(case when result ='胜' then 1 else 0 end)'胜',
sum(case when result ='负'then 1 else 0 end)'负'
from Match_record
group by Match_date
# 获取每个班级的最后一名
select bj,min(score) m 
from stu_score
group by bj

select ss.*
from stu_score ss
join  (select bj,min(score) m 
from stu_score
group by bj)temp 
on temp.bj = ss.bj and ss.score = temp.m

标签:01,join,name,复杂,stu,score,SQL,id,select
来源: https://www.cnblogs.com/yzoran/p/16489127.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有