2016-11-26 81 views
2

Student_table学生报名参加同一课程

std_name course_enrolled 
S1   C1 
S1   C2 
S2   C1 
S3   C4 
S4   C1 
S4   C2 
S5   C1 

我想选择谁已经报名参加同一门课程像S1 & S4报名参加C1 C2 &学生,S2 & S5报名参加C1 ......这样的。这只是表的一个snopshot,实际的表将包含更多的数据。 请给我同样的SQL查询。

+0

请用您正在使用的数据库标记您的问题。另外,这些课程必须完全一样吗? –

+0

Oracle数据库。相同的课程意味着它应该是相同的。我仅仅为此描述了描述。谢谢 –

回答

0

使用标准的SQL,你可以这样做:

with s as (
     select s.*, count(*) over (partition by std_name) as num_courses 
     from student_table s 
    ) 
select s1.std_name, s2.std_name 
from s s1 join 
    s s2 
    on s1.std_name < s2.std_name and 
     s1.num_courses = s2.num_courses and 
     s1.course_enrolled = s2.course_enrolled 
group by s1.std_name, s2.std_name 
having count(*) = max(s1.num_courses); 

这是一个相当棘手的自联接。但基本上它是说“匹配课程的数量是一个学生参加的课程的数量。”

1
create table student_enrolled(student varchar2(20),course varchar2(20)); 

insert into student_enrolled values('S1',   'C1'); 
insert into student_enrolled values('S1',   'C2'); 
insert into student_enrolled values('S2',   'C1'); 
insert into student_enrolled values('S3',   'C4'); 
insert into student_enrolled values('S4',   'C1'); 
insert into student_enrolled values('S4',   'C2'); 
insert into student_enrolled values('S5',   'C1'); 

select * from student_enrolled; 

STUDENT    COURSE    
-------------------- -------------------- 
S1     C1     
S1     C2     
S2     C1     
S3     C4     
S4     C1     
S4     C2     
S5     C1  



select s1.student , s2.student, s1.course as common_course 
from student_enrolled s1 join student_enrolled s2 on (s1.course=s2.course) 
where 
-- to not show student with himself 
s1.student<>s2.student and 
not exists (
    -- all courses enrolled by s2 not enrolled by s1 
    select 1 from student_enrolled s3 where s3.student=s2.student and not exists (select 1 from student_enrolled s4 where s4.student=s1.student and s4.course=s3.course)) 
and 
not exists (
    -- all courses enrolled by s1 not enrolled by s2 
    select 1 from student_enrolled s5 where s5.student=s1.student and not exists (select 1 from student_enrolled s6 where s6.student=s2.student and s6.course=s5.course)) 

order by 1,2 ; 

STUDENT1    STUDENT2    COMMON_COURSE  
-------------------- -------------------- -------------------- 
S1     S4     C1     
S1     S4     C2     
S2     S5     C1     
S4     S1     C1     
S4     S1     C2     
S5     S2     C1