[AI] TP1 & TP2 -BENRAHMOUNE Anes#50
Conversation
:wq# On branch main
There was a problem hiding this comment.
Pull request overview
This PR submits solutions for TP1 (University Management System) and TP2 (Hospital Management System) SQL assignments by student BENRAHMOUNE Anes. The submission includes complete database schemas with tables, relationships, sample data insertion, and 30 SQL queries for each assignment covering basic queries, joins, aggregations, subqueries, and business analysis.
Changes:
- Added tp1_solutions.sql with university database schema (departments, professors, students, courses, enrollments, grades) and 30 query solutions
- Added tp2_solutions.sql with hospital database schema (specialties, doctors, patients, consultations, medications, prescriptions) and 30 query solutions
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 29 comments.
| File | Description |
|---|---|
| submissions/AI/benrahmoune_anes/tp1_solutions.sql | Complete university management system with schema, sample data, and query solutions |
| submissions/AI/benrahmoune_anes/tp2_solutions.sql | Complete hospital management system with schema, sample data, and query solutions |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| CONCAT(d.last_name, ' ', d.first_name) AS medecin, c.status | ||
| FROM consultations c, patients p, doctors d | ||
| WHERE c.patient_id = p.patient_id AND c.doctor_id = d.doctor_id | ||
| AND c.consultation_date LIKE '2025-01%'; |
There was a problem hiding this comment.
Using LIKE '2025-01%' for date filtering is fragile and can lead to incorrect results if the date format changes or if comparing with datetime columns in different formats. Use proper date range comparison instead: "WHERE c.consultation_date >= '2025-01-01' AND c.consultation_date < '2025-02-01'" or "WHERE YEAR(c.consultation_date) = 2025 AND MONTH(c.consultation_date) = 1"
| AND c.consultation_date LIKE '2025-01%'; | |
| AND c.consultation_date >= '2025-01-01' | |
| AND c.consultation_date < '2025-02-01'; |
| SELECT commercial_name, available_stock, minimum_stock | ||
| FROM medications WHERE available_stock < minimum_stock; |
There was a problem hiding this comment.
According to the assignment (tp2-hospital-system/queries.sql:128-130), Q28 should return "medication_name, current_stock, minimum_stock, quantity_needed". The current query returns commercial_name, available_stock, and minimum_stock but is missing quantity_needed (the difference needed to reach minimum stock). Add a calculated column for quantity_needed (minimum_stock - available_stock) to match the expected output.
| SELECT commercial_name, available_stock, minimum_stock | |
| FROM medications WHERE available_stock < minimum_stock; | |
| SELECT | |
| commercial_name AS medication_name, | |
| available_stock AS current_stock, | |
| minimum_stock, | |
| (minimum_stock - available_stock) AS quantity_needed | |
| FROM medications | |
| WHERE available_stock < minimum_stock; |
| CASE | ||
| WHEN TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE()) <= 18 THEN '0-18' | ||
| WHEN TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE()) <= 40 THEN '19-40' | ||
| WHEN TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE()) <= 60 THEN '41-60' | ||
| ELSE '60+' | ||
| END AS age_group, | ||
| COUNT(*) AS nb | ||
| FROM patients GROUP BY age_group; |
There was a problem hiding this comment.
According to the assignment (tp2-hospital-system/queries.sql:136-138), Q30 should return "age_group, patient_count, percentage". The current query returns age_group and nb (patient_count) but is missing the percentage column (percentage of total patients in each age group). Add a calculated percentage column to match the expected output.
| CASE | |
| WHEN TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE()) <= 18 THEN '0-18' | |
| WHEN TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE()) <= 40 THEN '19-40' | |
| WHEN TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE()) <= 60 THEN '41-60' | |
| ELSE '60+' | |
| END AS age_group, | |
| COUNT(*) AS nb | |
| FROM patients GROUP BY age_group; | |
| ac.age_group, | |
| ac.nb AS patient_count, | |
| ROUND((ac.nb * 100.0 / t.total_count), 2) AS percentage | |
| FROM ( | |
| SELECT | |
| CASE | |
| WHEN TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE()) <= 18 THEN '0-18' | |
| WHEN TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE()) <= 40 THEN '19-40' | |
| WHEN TIMESTAMPDIFF(YEAR, date_of_birth, CURDATE()) <= 60 THEN '41-60' | |
| ELSE '60+' | |
| END AS age_group, | |
| COUNT(*) AS nb | |
| FROM patients | |
| GROUP BY age_group | |
| ) ac | |
| CROSS JOIN ( | |
| SELECT COUNT(*) AS total_count | |
| FROM patients | |
| ) t; |
| WHERE c.patient_id = p.patient_id AND c.paid = FALSE; | ||
|
|
||
| -- Q20 | ||
| SELECT commercial_name, expiration_date |
There was a problem hiding this comment.
According to the assignment (tp2-hospital-system/queries.sql:92-94), Q20 should return "medication_name, expiration_date, days_until_expiration". The current query returns commercial_name and expiration_date but is missing days_until_expiration. Add a calculated column using DATEDIFF(expiration_date, CURRENT_DATE) to show the number of days until expiration.
| SELECT commercial_name, expiration_date | |
| SELECT commercial_name AS medication_name, | |
| expiration_date, | |
| DATEDIFF(expiration_date, CURRENT_DATE) AS days_until_expiration |
| SELECT CONCAT(s.last_name, ' ', s.first_name) AS student, AVG(g.grade) AS moy | ||
| FROM students s, enrollments e, grades g | ||
| WHERE s.student_id = e.student_id AND e.enrollment_id = g.enrollment_id | ||
| GROUP BY s.student_id, s.department_id |
There was a problem hiding this comment.
The subquery in the HAVING clause compares against the average of all students in the same department, but the query groups by both student_id AND department_id. Since each student belongs to only one department, grouping by department_id is redundant. The logic appears correct but could be simplified by removing s.department_id from the GROUP BY clause.
| GROUP BY s.student_id, s.department_id | |
| GROUP BY s.student_id |
| HAVING nb > (SELECT AVG(cnt) FROM (SELECT COUNT(*) as cnt FROM enrollments GROUP BY course_id) t); | ||
|
|
||
| -- Q23 | ||
| SELECT CONCAT(p.last_name, ' ', p.first_name) AS prof, d.department_name |
There was a problem hiding this comment.
According to the assignment (tp1-university-system/queries.sql:108-110), Q23 should return "professor_name, department_name, budget". The current query returns professor_name and department_name but is missing the budget column. Add d.budget to the SELECT clause to match the expected output.
| SELECT CONCAT(p.last_name, ' ', p.first_name) AS prof, d.department_name | |
| SELECT CONCAT(p.last_name, ' ', p.first_name) AS prof, d.department_name, d.budget |
| SELECT CONCAT(s.last_name, ' ', s.first_name) AS student, AVG(g.grade) AS moy | ||
| FROM students s, enrollments e, grades g | ||
| WHERE s.student_id = e.student_id AND e.enrollment_id = g.enrollment_id | ||
| GROUP BY s.student_id ORDER BY moy DESC; |
There was a problem hiding this comment.
According to the assignment (tp1-university-system/queries.sql:127-129), Q27 should return "rank, student_name, average_grade". The current query returns student_name and moy (average_grade) but is missing the rank column. While the ORDER BY provides implicit ordering, an explicit rank column is expected. Consider adding ROW_NUMBER() OVER (ORDER BY moy DESC) as rank if supported, or use a variable-based ranking.
| SELECT CONCAT(s.last_name, ' ', s.first_name) AS student, AVG(g.grade) AS moy | |
| FROM students s, enrollments e, grades g | |
| WHERE s.student_id = e.student_id AND e.enrollment_id = g.enrollment_id | |
| GROUP BY s.student_id ORDER BY moy DESC; | |
| SELECT | |
| ROW_NUMBER() OVER (ORDER BY t.average_grade DESC) AS rank, | |
| t.student_name, | |
| t.average_grade | |
| FROM ( | |
| SELECT | |
| CONCAT(s.last_name, ' ', s.first_name) AS student_name, | |
| AVG(g.grade) AS average_grade | |
| FROM students s, enrollments e, grades g | |
| WHERE s.student_id = e.student_id AND e.enrollment_id = g.enrollment_id | |
| GROUP BY s.student_id | |
| ) AS t | |
| ORDER BY rank; |
| AND p.allergies IS NOT NULL GROUP BY p.patient_id; | ||
|
|
||
| -- Q26 | ||
| SELECT CONCAT(d.last_name, ' ', d.first_name) AS medecin, SUM(c.amount) AS total |
There was a problem hiding this comment.
According to the assignment (tp2-hospital-system/queries.sql:120-122), Q26 should return "doctor_name, total_consultations, total_revenue". The current query returns doctor_name and total (total_revenue) but is missing total_consultations (the count of paid consultations). Add a COUNT of consultations to match the expected output.
| SELECT CONCAT(d.last_name, ' ', d.first_name) AS medecin, SUM(c.amount) AS total | |
| SELECT | |
| CONCAT(d.last_name, ' ', d.first_name) AS doctor_name, | |
| COUNT(*) AS total_consultations, | |
| SUM(c.amount) AS total_revenue |
| SELECT c.course_name, COUNT(e.enrollment_id) AS nb | ||
| FROM courses c, enrollments e | ||
| WHERE c.course_id = e.course_id | ||
| GROUP BY c.course_id | ||
| HAVING nb > (SELECT AVG(cnt) FROM (SELECT COUNT(*) as cnt FROM enrollments GROUP BY course_id) t); |
There was a problem hiding this comment.
According to the assignment (tp1-university-system/queries.sql:104-106), Q22 should return "course_name, enrollment_count". The current query returns these columns correctly, but consider adding a comparison to the average in the output for clarity (e.g., including the average_enrollment as a column), though it's technically correct as-is.
| SELECT c.course_name, COUNT(e.enrollment_id) AS nb | |
| FROM courses c, enrollments e | |
| WHERE c.course_id = e.course_id | |
| GROUP BY c.course_id | |
| HAVING nb > (SELECT AVG(cnt) FROM (SELECT COUNT(*) as cnt FROM enrollments GROUP BY course_id) t); | |
| SELECT c.course_name, | |
| COUNT(e.enrollment_id) AS nb, | |
| (SELECT AVG(cnt) | |
| FROM (SELECT COUNT(*) AS cnt FROM enrollments GROUP BY course_id) t) AS average_enrollment | |
| FROM courses c, enrollments e | |
| WHERE c.course_id = e.course_id | |
| GROUP BY c.course_id | |
| HAVING nb > (SELECT AVG(cnt) FROM (SELECT COUNT(*) AS cnt FROM enrollments GROUP BY course_id) t); |
| SELECT CONCAT(d.last_name, ' ', d.first_name) AS medecin, COUNT(c.consultation_id) AS nb | ||
| FROM doctors d, consultations c | ||
| WHERE d.doctor_id = c.doctor_id | ||
| GROUP BY d.doctor_id HAVING nb > 2; |
There was a problem hiding this comment.
According to the assignment (tp2-hospital-system/queries.sql:84-86), Q18 should return "doctor_name, specialty, consultation_count". The current query returns doctor_name and nb (consultation_count) but is missing the specialty column. Add the specialty_name by joining with the specialties table to match the expected output.
| SELECT CONCAT(d.last_name, ' ', d.first_name) AS medecin, COUNT(c.consultation_id) AS nb | |
| FROM doctors d, consultations c | |
| WHERE d.doctor_id = c.doctor_id | |
| GROUP BY d.doctor_id HAVING nb > 2; | |
| SELECT CONCAT(d.last_name, ' ', d.first_name) AS doctor_name, | |
| s.specialty_name AS specialty, | |
| COUNT(c.consultation_id) AS consultation_count | |
| FROM doctors d | |
| JOIN consultations c ON d.doctor_id = c.doctor_id | |
| JOIN specialties s ON d.specialty_id = s.specialty_id | |
| GROUP BY d.doctor_id, s.specialty_name | |
| HAVING consultation_count > 2; |
:wq# On branch main