【发布时间】:2014-10-12 19:25:24
【问题描述】:
我想从
中找到所有同时注册两个或多个部分的不同学生对enroll(sid*, grade, dname*, cno*, sectno*)
每个部分由 (dname*, cno*, sectno*) 唯一标识
【问题讨论】:
我想从
中找到所有同时注册两个或多个部分的不同学生对enroll(sid*, grade, dname*, cno*, sectno*)
每个部分由 (dname*, cno*, sectno*) 唯一标识
【问题讨论】:
您可以在标识一个部分的列上自行加入,并指定e1.sid < e2.sid 以仅获取每对学生一次。
select e1.sid, e2.sid from enroll e1
join enroll e2 on e1.dname = e2.dname
and e1.cno = e2.cno
and e1.secno = e2.sectno
where e1.sid < e2.sid
group by e1.sid, e2.sid
having count(*) > 1
【讨论】:
distinct 使用 group by 和 having
/*
with enroll as (
select 1 sid, 'dname' dname, 1 cno, 1 secno from dual union all
select 1 sid, 'dname' dname, 1 cno, 1 secno from dual union all
select 2 sid, 'dname' dname, 1 cno, 1 secno from dual union all
select 3 sid, 'dname' dname, 1 cno, 1 secno from dual union all
select 1 sid, 'dname' dname, 2 cno, 2 secno from dual union all
select 2 sid, 'dname' dname, 2 cno, 2 secno from dual
)
*/
select e1.sid, e2.sid from enroll e1
join enroll e2 on e1.dname = e2.dname
and e1.cno = e2.cno
and e1.secno = e2.secno
where e1.sid < e2.sid
group by e1.sid, e2.sid
having count(*) >= 2;
(但如果一个 sid 多次在同一部分注册,则此查询将无法正常工作)
【讨论】:
with enroll as (
select 1 sid, 'dname' dname, 1 cno, 1 secno from dual union all
select 1 sid, 'dname' dname, 1 cno, 1 secno from dual union all
select 2 sid, 'dname' dname, 1 cno, 1 secno from dual union all
select 3 sid, 'dname' dname, 1 cno, 1 secno from dual union all
select 3 sid, 'dname' dname, 1 cno, 1 secno from dual union all
select 1 sid, 'dname' dname, 2 cno, 2 secno from dual union all
select 2 sid, 'dname' dname, 2 cno, 2 secno from dual
)
select rn,sid from (
select row_number() over (partition by sid order by dname) as rn ,sid
from enroll )
where rn>1
使用 row_number()
如果一个 sid 多次在同一部分注册,则此查询正常工作
如果需要,可以使用distinct
with enroll as (
select 1 sid, 'dname' dname, 1 cno, 1 secno from dual union all
select 1 sid, 'dname' dname, 1 cno, 1 secno from dual union all
select 2 sid, 'dname' dname, 1 cno, 1 secno from dual union all
select 3 sid, 'dname' dname, 1 cno, 1 secno from dual union all
select 3 sid, 'dname' dname, 1 cno, 1 secno from dual union all
select 1 sid, 'dname' dname, 2 cno, 2 secno from dual union all
select 4 sid, 'dname' dname, 2 cno, 2 secno from dual union all
select 2 sid, 'dname' dname, 2 cno, 2 secno from dual
)
select distinct sid from (
select row_number() over (partition by sid order by dname) as rn ,sid
from enroll )
where rn>1
输出
> SID
> ----------
> 1
> 2
> 3
【讨论】: