Oracle SQL当数据集的数量是动态的时,是否有一种方法可以找到存储在同一表中的数据集的交集

时间:2019-07-04 05:28:32

标签: sql oracle relational-division

想象一下以下数据集。 (这不是我正在研究的完全相同的问题,但这只是一个演示需求的简单示例)

Student ID,  Course ID
S1           C1
S1           C2
S1           C3
S2           C1
S2           C3
S3           C1
S3           C2

在以上数据集中,每个学生的课程号都被注册了。我想找出导致此表中所有原因的学生。

因此,如果我使用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引擎(可能正在使用分析函数),因为涉及的数据集可能很大。

2 个答案:

答案 0 :(得分:4)

尝试这样的事情:

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>)

这样,您可以确保为student_id中指定的每个course_id注册每个返回的<anothertable>

这称为“关系部门”,另请参见https://www.red-gate.com/simple-talk/sql/t-sql-programming/divided-we-stand-the-sql-of-relational-division/

编辑(作者戈登):

在该问题中仅提及一个表,因此查询为:

SELECT student_id
FROM t
GROUP BY student_id 
HAVING COUNT(DISTINCT course_id) = (SELECT COUNT(DISTINCT course_id) FROM t)

答案 1 :(得分:3)

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 

DEMO