Oracle SQL 当数据集的数量是动态的时,有没有办法找到存储在同一个 table 中的数据集的交集
Oracle SQL Is there a way to find intersections of data sets stored in same table when number of data sets are dynamic
想象一下下面的数据集。 (这不是我正在处理的完全相同的问题,但这只是一个演示要求的简单示例)
Student ID, Course ID
S1 C1
S1 C2
S1 C3
S2 C1
S2 C3
S3 C1
S3 C2
在上面的数据集中,每个学生都在课程数量下注册。我想找出这table.
中的所有原因都是哪些学生
因此,如果我使用 INTERSECT 关键字,它将如下所示。
SELECT student_id FROM <table> where course_id = 'C1'
INTERSECT
SELECT student_id FROM <table> where course_id = 'C2'
INTERSECT
SELECT student_id FROM <table> where course_id = 'C3'
显然只有在课程列表固定的情况下才有效。
有没有办法做到这一点,课程列表是动态的并且只使用 SQL。
我可以编写一个 PLSQL 函数来执行此操作。但是随后将为每个唯一的课程 ID 执行一个游标,交集将由 PLSQL 代码完成。
我正在寻找是否可以将尽可能多的数据卸载到 SQL 引擎(可能正在使用分析函数),因为涉及的数据集可能很大。
尝试这样的事情:
SELECT student_id FROM <table>
WHERE course_id IN (SELECT course_id FROM <anothertable>)
GROUP BY student_id
HAVING COUNT(DISTINCT course_id)=(SELECT COUNT(DISTINCT course_id) FROM <anothertable>)
这样,您可以确保为 <anothertable>
中指定的每个 course_id
注册每个返回的 student_id
。
这叫做"Relational Division",另见https://www.red-gate.com/simple-talk/sql/t-sql-programming/divided-we-stand-the-sql-of-relational-division/
编辑(戈登):
问题中只提到了一个table,所以查询是:
SELECT student_id
FROM t
GROUP BY student_id
HAVING COUNT(DISTINCT course_id) = (SELECT COUNT(DISTINCT course_id) FROM t)
Oracle 允许您使用 COUNT(DISTINCT)
作为解析函数。
所以,你可以这样做:
SELECT DISTINCT student_id
FROM (SELECT student_id,
COUNT(DISTINCT course_id)
OVER ( PARTITION BY student_id ) AS course_per_student,
COUNT(DISTINCT course_id) OVER () AS available_courses
FROM t)
WHERE course_per_student = available_courses
想象一下下面的数据集。 (这不是我正在处理的完全相同的问题,但这只是一个演示要求的简单示例)
Student ID, Course ID
S1 C1
S1 C2
S1 C3
S2 C1
S2 C3
S3 C1
S3 C2
在上面的数据集中,每个学生都在课程数量下注册。我想找出这table.
中的所有原因都是哪些学生因此,如果我使用 INTERSECT 关键字,它将如下所示。
SELECT student_id FROM <table> where course_id = 'C1'
INTERSECT
SELECT student_id FROM <table> where course_id = 'C2'
INTERSECT
SELECT student_id FROM <table> where course_id = 'C3'
显然只有在课程列表固定的情况下才有效。
有没有办法做到这一点,课程列表是动态的并且只使用 SQL。
我可以编写一个 PLSQL 函数来执行此操作。但是随后将为每个唯一的课程 ID 执行一个游标,交集将由 PLSQL 代码完成。
我正在寻找是否可以将尽可能多的数据卸载到 SQL 引擎(可能正在使用分析函数),因为涉及的数据集可能很大。
尝试这样的事情:
SELECT student_id FROM <table>
WHERE course_id IN (SELECT course_id FROM <anothertable>)
GROUP BY student_id
HAVING COUNT(DISTINCT course_id)=(SELECT COUNT(DISTINCT course_id) FROM <anothertable>)
这样,您可以确保为 <anothertable>
中指定的每个 course_id
注册每个返回的 student_id
。
这叫做"Relational Division",另见https://www.red-gate.com/simple-talk/sql/t-sql-programming/divided-we-stand-the-sql-of-relational-division/
编辑(戈登):
问题中只提到了一个table,所以查询是:
SELECT student_id
FROM t
GROUP BY student_id
HAVING COUNT(DISTINCT course_id) = (SELECT COUNT(DISTINCT course_id) FROM t)
Oracle 允许您使用 COUNT(DISTINCT)
作为解析函数。
所以,你可以这样做:
SELECT DISTINCT student_id
FROM (SELECT student_id,
COUNT(DISTINCT course_id)
OVER ( PARTITION BY student_id ) AS course_per_student,
COUNT(DISTINCT course_id) OVER () AS available_courses
FROM t)
WHERE course_per_student = available_courses