QueryOptimization: meta-functions.sql

File meta-functions.sql, 9.7 KB (added by 231082, 4 days ago)

Functional optimization of the two VIEWs.

Line 
1
2-- FOR v_student_registration_state VIEW
3CREATE OR REPLACE FUNCTION fn_student_registration_state(p_student_id INTEGER)
4 RETURNS TABLE (
5 student_id INTEGER,
6 academic_program_code TEXT,
7 course_code TEXT,
8 course_name TEXT,
9 credits INTEGER,
10 mandatory BOOLEAN,
11 curriculum_semester SMALLINT,
12 already_passed BOOLEAN,
13 currently_enrolled BOOLEAN,
14 prerequisites_met BOOLEAN,
15 missing_prereq_count BIGINT,
16 credit_headroom BIGINT,
17 would_exceed_cap BOOLEAN,
18 can_enroll BOOLEAN,
19 enrollment_status TEXT
20 )
21 LANGUAGE plpgsql STABLE
22AS $$
23BEGIN
24 RETURN QUERY
25 WITH
26 active_pe AS (
27 SELECT pe.id AS pe_id, pe.academic_program_code
28 FROM Program_Enrollment pe
29 WHERE pe.student_id = p_student_id
30 AND pe.date_disenrollment IS NULL
31 AND pe.finished IS NOT TRUE
32 ),
33 passed_courses AS (
34 SELECT DISTINCT ed.course_code AS passed_code
35 FROM active_pe ape
36 JOIN Semester_Enrollment se ON se.program_enrollment_id = ape.pe_id
37 JOIN Course_Enrollment ce ON ce.semester_enrollment_id = se.id
38 JOIN Course_Edition ed ON ed.id = ce.course_edition_id
39 JOIN Student_Grade sg ON sg.course_enrollment_id = ce.id
40 ),
41 passed_with_equiv AS (
42 SELECT passed_code FROM passed_courses
43 UNION
44 SELECT eq.course2_code
45 FROM passed_courses pc
46 JOIN Course_Equivalence eq ON eq.course1_code = pc.passed_code
47 UNION
48 SELECT eq.course1_code
49 FROM passed_courses pc
50 JOIN Course_Equivalence eq ON eq.course2_code = pc.passed_code
51 ),
52 current_enrollments AS (
53 SELECT ed.course_code AS curr_code
54 FROM active_pe ape
55 JOIN Semester_Enrollment se ON se.program_enrollment_id = ape.pe_id
56 AND se.academic_year = 2025 AND (se.semester::int) = 1 -- cast to int, compare to 1
57 JOIN Course_Enrollment ce ON ce.semester_enrollment_id = se.id
58 JOIN Course_Edition ed ON ed.id = ce.course_edition_id
59 ),
60 current_credits AS (
61 SELECT COALESCE(SUM(c.credits), 0) AS credits_consumed
62 FROM active_pe ape
63 LEFT JOIN Semester_Enrollment se ON se.program_enrollment_id = ape.pe_id
64 AND se.academic_year = 2025 AND (se.semester::int) = 1
65 LEFT JOIN Course_Enrollment ce ON ce.semester_enrollment_id = se.id
66 LEFT JOIN Course_Edition ed ON ed.id = ce.course_edition_id
67 LEFT JOIN Course c ON c.code = ed.course_code
68 ),
69 prereq_check AS (
70 SELECT
71 cur.course_code AS prereq_course,
72 COUNT(cp.predecessor_course_code) AS total_prereqs,
73 COUNT(pwe.passed_code) AS met_prereqs
74 FROM active_pe ape
75 CROSS JOIN Curriculum cur
76 LEFT JOIN Course_Prerequisite cp ON cp.successor_course_code = cur.course_code
77 LEFT JOIN passed_with_equiv pwe ON pwe.passed_code = cp.predecessor_course_code
78 WHERE cur.academic_program_code = ape.academic_program_code
79 GROUP BY cur.course_code
80 )
81 SELECT
82 p_student_id,
83 ape.academic_program_code,
84 cur.course_code,
85 c.name,
86 c.credits,
87 cur.mandatory,
88 cur.semester,
89 (pwe.passed_code IS NOT NULL) AS already_passed,
90 (ce_now.curr_code IS NOT NULL) AS currently_enrolled,
91 COALESCE(pc.total_prereqs IS NULL OR pc.met_prereqs = pc.total_prereqs, TRUE) AS prerequisites_met,
92 COALESCE(pc.total_prereqs - pc.met_prereqs, 0) AS missing_prereq_count,
93 40 - cc.credits_consumed AS credit_headroom,
94 (40 - cc.credits_consumed) < c.credits AS would_exceed_cap,
95 CASE
96 WHEN pwe.passed_code IS NOT NULL THEN FALSE
97 WHEN ce_now.curr_code IS NOT NULL THEN FALSE
98 WHEN pc.total_prereqs IS NOT NULL AND pc.met_prereqs < pc.total_prereqs THEN FALSE
99 WHEN (40 - cc.credits_consumed) < c.credits THEN FALSE
100 ELSE TRUE
101 END AS can_enroll,
102 CASE
103 WHEN pwe.passed_code IS NOT NULL THEN 'already_passed'
104 WHEN ce_now.curr_code IS NOT NULL THEN 'currently_enrolled'
105 WHEN pc.total_prereqs IS NOT NULL AND pc.met_prereqs < pc.total_prereqs THEN 'prerequisites_not_met'
106 WHEN (40 - cc.credits_consumed) < c.credits THEN 'credit_cap_exceeded'
107 ELSE 'eligible'
108 END AS enrollment_status
109 FROM active_pe ape
110 CROSS JOIN Curriculum cur
111 JOIN Course c ON c.code = cur.course_code
112 LEFT JOIN passed_with_equiv pwe ON pwe.passed_code = cur.course_code
113 LEFT JOIN current_enrollments ce_now ON ce_now.curr_code = cur.course_code
114 LEFT JOIN prereq_check pc ON pc.prereq_course = cur.course_code
115 CROSS JOIN current_credits cc
116 WHERE cur.academic_program_code = ape.academic_program_code;
117END;
118$$;
119
120
121
122
123
124-- FOR v_teaching_assistant_eligibility VIEW
125CREATE OR REPLACE FUNCTION fn_teaching_assistant_eligibility(p_edition_id INTEGER)
126 RETURNS TABLE (
127 student_id INTEGER,
128 student_index TEXT,
129 student_name TEXT,
130 edition_id INTEGER,
131 academic_year SMALLINT,
132 semester SMALLINT,
133 course_code TEXT,
134 course_name TEXT,
135 eligible_supervisors TEXT,
136 times_enrolled BIGINT
137 )
138 LANGUAGE plpgsql STABLE
139AS $$
140DECLARE
141 var_course_code TEXT;
142 var_academic_year SMALLINT;
143 var_semester SMALLINT;
144BEGIN
145 SELECT ed.course_code, ed.academic_year, ed.semester
146 INTO var_course_code, var_academic_year, var_semester
147 FROM Course_Edition ed
148 WHERE ed.id = p_edition_id;
149
150 IF NOT FOUND THEN
151 RETURN;
152 END IF;
153
154 RETURN QUERY
155 WITH
156 course_passers AS (
157 SELECT DISTINCT pe.student_id
158 FROM Program_Enrollment pe
159 JOIN Semester_Enrollment se ON se.program_enrollment_id = pe.id
160 JOIN Course_Enrollment ce ON ce.semester_enrollment_id = se.id
161 JOIN Course_Edition ed ON ed.id = ce.course_edition_id
162 JOIN Student_Grade sg ON sg.course_enrollment_id = ce.id
163 WHERE ed.course_code = var_course_code
164 ),
165 currently_enrolled AS (
166 SELECT DISTINCT pe.student_id
167 FROM Program_Enrollment pe
168 JOIN Semester_Enrollment se ON se.program_enrollment_id = pe.id
169 AND se.academic_year = var_academic_year
170 AND (se.semester::int) = var_semester -- compare to SMALLINT variable, cast semester to int
171 JOIN Course_Enrollment ce ON ce.semester_enrollment_id = se.id
172 WHERE ce.course_edition_id = p_edition_id
173 ),
174 existing_tas AS (
175 SELECT ta.student_id
176 FROM Teaching_Assistant ta
177 JOIN Teaches tt ON tt.teacher_id = ta.teacher_id
178 WHERE tt.course_edition_id = p_edition_id
179 ),
180 supervisors AS (
181 SELECT STRING_AGG(m.name || ' ' || m.surname, ', ' ORDER BY m.surname) AS names
182 FROM Teaches t
183 JOIN Member m ON m.id = t.teacher_id
184 WHERE t.course_edition_id = p_edition_id
185 ),
186 times_taken AS (
187 SELECT
188 pe.student_id,
189 COUNT(DISTINCT ce.id) AS cnt
190 FROM Program_Enrollment pe
191 JOIN Semester_Enrollment se ON se.program_enrollment_id = pe.id
192 JOIN Course_Enrollment ce ON ce.semester_enrollment_id = se.id
193 JOIN Course_Edition ed ON ed.id = ce.course_edition_id
194 WHERE ed.course_code = var_course_code
195 GROUP BY pe.student_id
196 )
197 SELECT
198 s.id,
199 s.index,
200 m.name || ' ' || m.surname,
201 p_edition_id,
202 var_academic_year,
203 var_semester,
204 c.code,
205 c.name,
206 supervisors.names,
207 COALESCE(times_taken.cnt, 0)::BIGINT
208 FROM course_passers cp
209 JOIN Student s ON s.id = cp.student_id
210 JOIN Member m ON m.id = s.id
211 CROSS JOIN Course c
212 CROSS JOIN supervisors
213 LEFT JOIN currently_enrolled ce ON ce.student_id = cp.student_id
214 LEFT JOIN existing_tas et ON et.student_id = cp.student_id
215 LEFT JOIN times_taken ON times_taken.student_id = cp.student_id
216 WHERE ce.student_id IS NULL
217 AND et.student_id IS NULL
218 AND c.code = var_course_code;
219END;
220$$;