Oracle:根据其他列中的值选择列的值

Oracle : Selecting the values of column based on the values in other column

我想要 table 如下所示:

Class_ID    Student_ID     Sub_ID
3171         10577752         1
3171         10577753         1
3171         10577753         2
3171         10577754         1
3171         10577755         1
3171         10577755         2
3172         10577756         1
3172         10577756         2
3172         10577756         3
3172         10577757         1
3172         10577757         2
3172         10577758         1

所以我想 select 所有 sub_id 中的 student_id。为了。例如:在 class_id 3171 中,总 sub_id 是 2(1 和 2),student_id 10577753 在 sub_id 1 和 2 中都有,但 id 10577752 仅存在于 sub_id 1 中。所以我想 select 10577753 和 10577755 用于 class_id 3171。Class_ID 2172 总共有 sub_id 3(1 ,2,3) 和 student_id 10577756 在所有三个中都存在。所以我只想 select 上面的 student_id 10577753,10577755,10577756 table.

计数不同。使用 HAVING 子句将学生的计数与其 类 的计数进行比较。

select class_id, student_id
from mytable t1
group by class_id, student_id
having count(distinct sub_id) =
(
  select count(distinct sub_id)
  from mytable t2
  where t2.class_id = t1.class_id
)
order by class_id, student_id;

另一种写法:

select class_id, student_id
from mytable
group by class_id, student_id
having (class_id, count(distinct sub_id)) in
(
  select class_id, count(distinct sub_id)
  from mytable
  group by class_id
)
order by class_id, student_id;

区别在于第一个查询使用相关子查询,第二个查询使用非相关子查询。但是他们终究是做同样的事情。

这是一个选项(样本数据到第 26 行):temp CTE 计算不同 STU_ID 的数量,按学生 (cnt_stu) 或 class 划分(cnt_tot)。 获胜者 是计数匹配的学生。

SQL> WITH
  2     test (class_id, student_id, sub_id)
  3     AS
  4        (SELECT 3171, 10577752, 1 FROM DUAL
  5         UNION ALL
  6         SELECT 3171, 10577753, 1 FROM DUAL
  7         UNION ALL
  8         SELECT 3171, 10577753, 2 FROM DUAL
  9         UNION ALL
 10         SELECT 3171, 10577754, 1 FROM DUAL
 11         UNION ALL
 12         SELECT 3171, 10577755, 1 FROM DUAL
 13         UNION ALL
 14         SELECT 3171, 10577755, 2 FROM DUAL
 15         UNION ALL
 16         SELECT 3172, 10577756, 1 FROM DUAL
 17         UNION ALL
 18         SELECT 3172, 10577756, 2 FROM DUAL
 19         UNION ALL
 20         SELECT 3172, 10577756, 3 FROM DUAL
 21         UNION ALL
 22         SELECT 3172, 10577757, 1 FROM DUAL
 23         UNION ALL
 24         SELECT 3172, 10577757, 2 FROM DUAL
 25         UNION ALL
 26         SELECT 3172, 10577758, 1 FROM DUAL),

 27     temp
 28     AS
 29        (SELECT class_id,
 30                student_id,
 31                sub_id,
 32                COUNT (DISTINCT sub_id)
 33                   OVER (PARTITION BY class_id, student_id) cnt_stu,
 34                COUNT (DISTINCT sub_id) OVER (PARTITION BY class_id) cnt_tot
 35           FROM test)
 36    SELECT DISTINCT student_id
 37      FROM temp
 38     WHERE cnt_stu = cnt_tot
 39  ORDER BY student_id;

STUDENT_ID
----------
  10577753
  10577755
  10577756

SQL>