今天在溫習oracle 數據庫習題,寫到這個題目發現不會做,看答案發現是錯的,之前居然不知道,網上百度了一些,很多結果都不對,要么就看不懂,請原諒我的無知。
好吧,雖然沒有找到簡單易懂的答案,但是也給了我一些靈感,好吧,下班前終於做出來了,OMG!
題目:查詢和“s002”號的同學學習的課程完全相同的其他同學學號和姓名
表結構:
/*學生表*/
create table student(
sno varchar2(10) primary key,
sname varchar2(20),
sage number(2),
ssex varchar2(5)
);
/*成績表*/
create table sc(
sno varchar2(10),
cno varchar2(10),
score number(4,2),
constraint pk_sc primary key (sno,cno)
);
插入數據:
/*******初始化學生表的數據******/
insert into student values ('s001','張三',23,'男');
insert into student values ('s002','李四',23,'男');
insert into student values ('s003','吳鵬',25,'男');
insert into student values ('s004','琴沁',20,'女');
insert into student values ('s005','王麗',20,'女');
insert into student values ('s006','李波',21,'男');
insert into student values ('s007','劉玉',21,'男');
insert into student values ('s008','蕭蓉',21,'女');
insert into student values ('s009','陳蕭曉',23,'女');
insert into student values ('s010','陳美',22,'女');
commit;
/***************初始化成績表***********************/
insert into sc values ('s001','c001',78.9);
insert into sc values ('s002','c001',80.9);
insert into sc values ('s003','c001',81.9);
insert into sc values ('s004','c001',60.9);
insert into sc values ('s001','c002',82.9);
insert into sc values ('s002','c002',72.9);
insert into sc values ('s003','c002',81.9);
insert into sc values ('s001','c003','59');
insert into sc values ('s006','c001',72);
insert into sc values ('s005','c001',80);
insert into sc values ('s005','c002',81);
insert into sc values ('s006','c003',67);
insert into sc values ('s001','c004',83);
insert into sc values ('s001','c005',80);
insert into sc values ('s001','c006',79);
commit;
-------------------------分割線-----------------------------------------------------
好了,開始正題:
《1》找到所有和s002任意課程相同的同學
select s1.sno from sc s1 join sc s2 on s1.cno=s2.cno where s1.sno<>'s002' and s2.sno ='s002'
<2> 步驟1 得到結果進行分組,按sno
select sno, count(*) from (select s1.sno from sc s1 join sc s2 on s1.cno=s2.cno where s1.sno<>'s002' and s2.sno ='s002') group by sno
<3>對結果進行篩選,選出相同課程數和s002一樣的同學
select sno, count(*) from (select s1.sno from sc s1 join sc s2 on s1.cno=s2.cno where s1.sno<>'s002' and s2.sno ='s002') group by sno having count(*) = (select count(*) from sc where sno='s002')
<4>到這里是不是結束了呢,不是,有一種情況,A學了s002所有的課程,還學了其他的課程所以需要再次排除
select sno,count(*) from sc group by sno intersect ( select sno, count(*) from (select s1.sno from sc s1 join sc s2 on s1.cno=s2.cno where s1.sno<>'s002' and s2.sno ='s002') group by sno having count(*) = (select count(*) from sc where sno='s002') )
<5>然后提取出學號
select sno from (select sno,count(*) from sc group by sno intersect ( select sno, count(*) from (select s1.sno from sc s1 join sc s2 on s1.cno=s2.cno where s1.sno<>'s002' and s2.sno ='s002') group by sno having count(*) = (select count(*) from sc where sno='s002') ))
<6>最后一步
select sno,sname from (select sno from (select sno,count(*) from sc group by sno intersect ( select sno, count(*) from (select s1.sno from sc s1 join sc s2 on s1.cno=s2.cno where s1.sno<>'s002' and s2.sno ='s002') group by sno having count(*) = (select count(*) from sc where sno='s002') )) )
ps:(紅色部分為每次步驟新增的內容,方便理解)
