我怎么知道已经学过课程先决条件的学生人数?

时间:2016-03-20 20:25:00

标签: sql oracle

我正在尝试实现一个查询,该查询选择已经取得特定课程先决条件的学生人数,如果课程只有一个先决条件,但是如果有许多先决条件,我可以使用连接语句来实现它我遇到了麻烦, 我有这个查询所需的以下表格

enroll(  Student_id,course_id,semester)
studyplan(major_id,course_id, creditHours)
prerequisite(course_id, prerequisite_id)
请帮忙......我的时间不多了。

2 个答案:

答案 0 :(得分:1)

您可以使用COLLECT aggreagtion函数和SUBMULTISET运算符来执行此操作。

Oracle设置

CREATE TABLE Courses ( ID INT PRIMARY KEY );
CREATE TABLE Students ( ID INT PRIMARY KEY );
CREATE TABLE Enroll(
  Student_ID INT REFERENCES Students(ID),
  Course_ID  INT REFERENCES Courses(ID),
  Semester   DATE
);
CREATE TABLE StudyPlan(
  Major_ID     INT,
  Course_ID    INT REFERENCES Courses(ID),
  Credit_Hours INT
);
CREATE TABLE Prerequisite(
  Course_ID       INT REFERENCES Courses(ID),
  Prerequisite_ID INT REFERENCES Courses(ID)
);

INSERT INTO Courses
SELECT LEVEL FROM DUAL CONNECT BY LEVEL <= 5;

INSERT INTO Students
SELECT LEVEL FROM DUAL CONNECT BY LEVEL <= 5;


INSERT INTO Prerequisite
SELECT 5, 1 FROM DUAL UNION ALL
SELECT 5, 2 FROM DUAL UNION ALL
SELECT 5, 3 FROM DUAL UNION ALL
SELECT 5, 4 FROM DUAL;

INSERT INTO Enroll
SELECT 1, 1, ADD_MONTHS( SYSDATE, -1 ) FROM DUAL UNION ALL
SELECT 1, 2, ADD_MONTHS( SYSDATE, -1 ) FROM DUAL UNION ALL
SELECT 1, 3, ADD_MONTHS( SYSDATE, -1 ) FROM DUAL UNION ALL
SELECT 2, 2, ADD_MONTHS( SYSDATE, -1 ) FROM DUAL UNION ALL
SELECT 2, 3, ADD_MONTHS( SYSDATE, -1 ) FROM DUAL UNION ALL
SELECT 2, 4, ADD_MONTHS( SYSDATE, -1 ) FROM DUAL UNION ALL
SELECT 3, 1, ADD_MONTHS( SYSDATE, -1 ) FROM DUAL UNION ALL
SELECT 3, 2, ADD_MONTHS( SYSDATE, -1 ) FROM DUAL UNION ALL
SELECT 3, 3, ADD_MONTHS( SYSDATE, -1 ) FROM DUAL UNION ALL
SELECT 3, 4, ADD_MONTHS( SYSDATE, -1 ) FROM DUAL UNION ALL
SELECT 4, 1, ADD_MONTHS( SYSDATE, -1 ) FROM DUAL UNION ALL
SELECT 4, 2, ADD_MONTHS( SYSDATE, -1 ) FROM DUAL UNION ALL
SELECT 4, 3, ADD_MONTHS( SYSDATE,  1 ) FROM DUAL UNION ALL
SELECT 4, 4, ADD_MONTHS( SYSDATE,  1 ) FROM DUAL UNION ALL
SELECT 5, 1, ADD_MONTHS( SYSDATE, -1 ) FROM DUAL UNION ALL
SELECT 5, 2, ADD_MONTHS( SYSDATE, -1 ) FROM DUAL UNION ALL
SELECT 5, 3, ADD_MONTHS( SYSDATE, -1 ) FROM DUAL UNION ALL
SELECT 5, 4, ADD_MONTHS( SYSDATE, -1 ) FROM DUAL;

CREATE OR REPLACE TYPE INTLIST AS TABLE OF INT;
/

<强>查询

WITH prereq ( prerequisite_ids ) AS (
  SELECT CAST( COLLECT( prerequisite_id ) AS INTLIST )
  FROM   Prerequisite
  WHERE  Course_ID = :courseid
),
enrollments ( student_id, course_ids ) AS (
  SELECT student_id,
         CAST( COLLECT( course_id ) AS INTLIST )
  FROM   enroll
  WHERE  semester < TO_DATE( :semester, 'YYYY-MM-DD' )
  GROUP BY student_id
)
SELECT student_id
FROM   prereq p
       INNER JOIN enrollments e
       ON ( p.prerequisite_ids SUBMULTISET OF e.course_ids );

<强>输出

绑定变量courseidsemester分别为5'2016-03-20'

STUDENT_ID
----------
         3 
         5 

学生1和2尚未注册必修课程。学生4已注册必修课程,但课程3和4在指定日期之后有学期,所以不计算在内。学生3和5具有所有先决条件并输出。

答案 1 :(得分:0)

你可以试试这个,但是什么决定学生已经采取了先决条件? 表格先决条件可能应该有Student_id字段......

select studyplan.course_id, count(Student_id)
from enroll, studyplan
where exists(select 1 from prerequisite where enroll.course_id = prerequisite.course_id)
and studyplan.course_id = enroll.course_id
group by studyplan.course_id