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>
我想要 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>