最近在刷题,越往后基础知识不扎实的短板就体现出来了。。。
- 查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
法1:
select * from sc as sc1,sc as sc2
where sc1.SId = sc2.SId
and sc1.CId <> sc2.CId
and sc1.score = sc2.score
结果

Q:结果中出现了重复数据
原因:
假如sc表中的数据如下
Sid CId Score
03 01 80
03 02 80
03 03 80
01 01 70
01 02 90
02 01 60
sc1和sc2在做inner join的时候,产生如下结果
Sid CId Score Sid CId Score
03 01 80 03 02 80
03 01 80 03 03 80
03 02 80 03 01 80
03 02 80 03 03 80
03 03 80 03 01 80
03 03 80 03 02 80
直接select *就产生了重复数据。
但是,用下面这个查询,就不会出现重复语句
select * from sc as sc1
where exists(select * from sc as sc2
where sc1.SId = sc2.SId
and sc1.CId <> sc2.CId
and sc1.score = sc2.score)
结果

原因:
那个 exists 函数后面的where 语句用到 sc1 的字段,sc1 在查询记录时就会把记录的值带入到 exists 后 where 语句,看返回的时 true 还是 false,是 true 就返回这条记录。
比如:
就比如说sc1中的
Sid CId Score
03 01 80
的这条记录代入到where查询语句中
返回了sc2中的两条记录
Sid CId Score
03 02 80
03 03 80
exists此时返回true,然后sc1的那条记录就查询出来了。
即代入语句能查询记录就会返回 true。
- 查询每门功成绩最好的前两名
select * from sc as sc1
where (select count(*) from sc as sc2 where sc1.CId = sc2.CId and sc2.score > sc1.score) < 2
order by CId,score desc;
结果

Q:不是很理解这个逻辑思路,实际逻辑如下
假设sc表中的数据如下
Sid CId Score
03 01 80
01 01 90
02 01 88
01 02 70
02 02 90
03 02 60
sc1、sc2 两个表不是直接做关联的,而是 sc1 表查询出来一条记录,就拿去和 sc2 表做关联,例如:查询到 01,01,80 分的这条记录时,就有判断
select count(1) from sc where sc.cid='01' and sc.score>80;
根据的假设的 sc2表的数据,
返回sc2表中的
Sid CId Score
01 01 90
02 01 88
这个结果应该是2,即比80分大的记录有两条,说明sc1表中的这条记录不是前两名,是第三名,所以 01,01,80 这条记录不符合要求 ,where 后面结果为 false,不会被查询出来;
如果查询到sc1表中的
Sid CId Score
02 01 88
这条记录,那么这条记录和sc2表做关联
返回sc2表中的
Sid CId Score
01 01 90
记录数为1,表明比sc1表中的这条记录大的只有一条,即该记录为第二大数据,满足where条件,where返回true,这条记录被查询出来,最大值的时候也类似。
网友评论