从oracle中重复的行中选择两个不同列的唯一值

时间:2019-02-05 09:48:51

标签: sql oracle oracle11g

表1

school_Name Student_Name Class_ID    
AMM          joe         AMM-1-1-1
AMM          joe         AMM-1-1-2
AMM          Adam        AMM-1-1-1
AMM          Adam        AMM-1-1-2
AMM          Nancy       AMM-1-2-1
AMM          Nancy       AMM-1-2-2
AMM          Albert      AMM-1-2-1
AMM          Albert      AMM-1-2-2
IRB          Frank       IRB-1-1-1
IRB          Frank       IRB-1-1-2
IRB          Mike        IRB-1-1-1
IRB          Mike        IRB-1-1-2

您好,我在oracle中有类似的表格,并试图为该学校的学生姓名的第1个匹配项选择唯一的class_id(1st)。任何人都可以帮忙。

选择语句的预期输出如下:

结果

school_Name Student_Name Class_ID    
AMM          joe         AMM-1-1-1
AMM          Adam        AMM-1-1-2
AMM          Nancy       AMM-1-2-1
AMM          Albert      AMM-1-2-2
IRB          Frank       IRB-1-1-1
IRB          Mike        IRB-1-1-2

在下面尝试过,但仍无法正常工作。

select 
  school_name,
  student_name,
  class_id, 
from 
(
  select
    school_name,
    student_name,
    class_id,
    row_number() over (partition by class_id order by student_name ASC) rn
  from studentdata_view
) where rn = 1;

3 个答案:

答案 0 :(得分:0)

您需要更改您的partition by子句,也从1st之前删除了多余的逗号

select school_name,student_name,class_id from 
(
   select school_name,student_name,class_id, row_number() over (partition by 
   school_name,student_name order by class_id ASC) rn from studentdata_view
)A where rn = 1;

答案 1 :(得分:0)

查询中的逗号过多:

select 
  school_name,
  student_name,
  class_id -- <=== it was here; I removed it 
from 
(
  select
    school_name,
    student_name,
    class_id,
    row_number() over (partition by class_id order by student_name ASC) rn
  from studentdata_view
) where rn = 1;

我还在您的partition by子句中将full_class_id更改为class_id

答案 2 :(得分:0)

所以您希望每个类在输出中仅出现一次?我认为您需要更复杂的算法。如果每个班级只有两个人“竞争”,这是应该起作用的,例如您的示例:

<table>
  <thead>
  <tr>
    <th>column 1</th>
    <th>column 2</th>
    <th>column 3</th>
  </tr>
  </thead>
  <tbody>
    <tr><td>a</td><td>b</td><td>c</td></tr>
    <tr><td>a</td><td>b</td><td>c</td></tr>
    <tr><td>a</td><td>b</td><td>c</td></tr>
    <tr><td>a</td><td>b</td><td>c</td></tr>
    <tr><td>a</td><td>b</td><td>c</td></tr>
    <tr><td>a</td><td>b</td><td>c</td></tr>
    <tr><td>a</td><td>b</td><td>c</td></tr>
    <tr><td>a</td><td>b</td><td>c</td></tr>
    <tr><td>a</td><td>b</td><td>c</td></tr>
  </tbody>
</table>

dbfiddle demo

结果:

select * 
  from (
    select school_name,student_name, class_id, 
           dense_rank() over (partition by school_name, class_id order by student_name) rnk,
           count(distinct student_name) over (partition by school_name, class_id) cnt,
           row_number() over (partition by school_name, student_name order by class_id ) rn
      from studentdata_view)
  where cnt = 1 
     or (cnt = 2 and ((rnk = 1 and rn = 1) or (rnk = 2 and rn = 2)))