【问题标题】:how to select unique tuples from same table如何从同一个表中选择唯一的元组
【发布时间】:2014-10-12 19:25:24
【问题描述】:

我想从

中找到所有同时注册两个或多个部分的不同学生对

enroll(sid*, grade, dname*, cno*, sectno*)

每个部分由 (dname*, cno*, sectno*) 唯一标识

【问题讨论】:

    标签: sql database oracle


    【解决方案1】:

    您可以在标识一个部分的列上自行加入,并指定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
    

    【讨论】:

    • 但我希望这对学生一起注册 2 个或更多部分。上面的查询给出了一对一起参加一个部分的人
    • @anvitapotluri 查看更新,而不是 distinct 使用 group byhaving
    【解决方案2】:
    /*
    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 多次在同一部分注册,则此查询将无法正常工作)

    【讨论】:

      【解决方案3】:
      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
      

      【讨论】:

        猜你喜欢
        • 2016-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-26
        • 1970-01-01
        • 2012-03-27
        • 1970-01-01
        相关资源
        最近更新 更多