DBMS Queries Exercises

Learning DBMS (Database Management System) queries mostly means getting fluent with SQL. The 80/20 rule applies: a handful of query patterns—SELECT, filtering, joins, grouping, subqueries—solve most real problems. Below is a focused set of exercises with a small sample schema and concise solutions to check your work.

Sample Schema (use these tables)

students(student_id, name, dept_id, cgpa, join_year)
departments(dept_id, dept_name)
courses(course_id, title, credits, dept_id)
enrollments(enroll_id, student_id, course_id, grade, semester)

Assume: grade like ‘A’,’B’,’C’,’D’,’F’. semester like ‘2024-Fall’.


Warm-Up (Basics)

  1. List all students.
  2. Show student names and CGPA for those with CGPA ≥ 8.0.
  3. Display unique semesters from enrollments (no duplicates).
  4. Sort courses by credits (high to low).
  5. Count total students.
  6. Find students who joined in 2023.
  7. Rename columns in output (e.g., student name as Student).

Joins (Most-used patterns)

  1. List student names with their department names.
  2. Show course titles with department names.
  3. All students and their enrolled courses (include students with no enrollments).
  4. For each enrollment, show student name, course title, and grade.
  5. Find students enrolled in courses outside their own department (cross-dept learning).

Aggregation & Grouping

  1. How many students per department?
  2. Average CGPA per department (desc by avg).
  3. Total enrollments per semester.
  4. For each course, count distinct students enrolled.
  5. Top 3 courses by enrollment count.

Filtering With Aggregates (HAVING)

  1. Departments with more than 50 students.
  2. Courses with average grade ‘A’ or ‘B’ (assume A=4,B=3,C=2,D=1,F=0).
  3. Students who took at least 5 courses.

Subqueries

  1. Students with CGPA above overall average.
  2. Courses with enrollment above the overall course average enrollment.
  3. Students who never received an ‘F’.
  4. Students who enrolled in every course of their department (set division pattern).

Window Functions (If supported)

  1. Rank students by CGPA within each department.
  2. Find each student’s latest semester grade per course (use row_number).

Data Quality / Admin

  1. Find duplicate student names (same name across different IDs).
  2. Find enrollments that reference non-existent students or courses (integrity check via anti-join).

Reference Solutions (concise)

Examples:

1

SELECT * FROM students;

2

SELECT name, cgpa FROM students WHERE cgpa >= 8.0;

3

SELECT DISTINCT semester FROM enrollments;

4

SELECT * FROM courses ORDER BY credits DESC;

5

SELECT COUNT(*) AS total_students FROM students;

6

SELECT * FROM students WHERE join_year = 2023;

7

SELECT name AS Student, cgpa AS CGPA FROM students;

8

SELECT s.name, d.dept_name
FROM students s
JOIN departments d ON s.dept_id = d.dept_id;

9

SELECT c.title, d.dept_name
FROM courses c
JOIN departments d ON c.dept_id = d.dept_id;

10

SELECT s.name, c.title
FROM students s
LEFT JOIN enrollments e ON s.student_id = e.student_id
LEFT JOIN courses c ON e.course_id = c.course_id;

11

SELECT s.name, c.title, e.grade
FROM enrollments e
JOIN students s  ON e.student_id = s.student_id
JOIN courses  c  ON e.course_id = c.course_id;

12

SELECT DISTINCT s.name
FROM enrollments e
JOIN students s ON e.student_id = s.student_id
JOIN courses c  ON e.course_id = c.course_id
WHERE s.dept_id <> c.dept_id;

13

SELECT d.dept_name, COUNT(*) AS student_count
FROM students s
JOIN departments d ON s.dept_id = d.dept_id
GROUP BY d.dept_name;

14

SELECT d.dept_name, AVG(s.cgpa) AS avg_cgpa
FROM students s
JOIN departments d ON s.dept_id = d.dept_id
GROUP BY d.dept_name
ORDER BY avg_cgpa DESC;

15

SELECT semester, COUNT(*) AS total_enrollments
FROM enrollments
GROUP BY semester;

16

SELECT c.title, COUNT(DISTINCT e.student_id) AS student_count
FROM courses c
LEFT JOIN enrollments e ON c.course_id = e.course_id
GROUP BY c.title;

17

SELECT c.title, COUNT(*) AS enrollments
FROM enrollments e
JOIN courses c ON e.course_id = c.course_id
GROUP BY c.title
ORDER BY enrollments DESC
FETCH FIRST 3 ROWS ONLY; -- or LIMIT 3

18

SELECT d.dept_name, COUNT(*) AS student_count
FROM students s
JOIN departments d ON s.dept_id = d.dept_id
GROUP BY d.dept_name
HAVING COUNT(*) > 50;

19 (map grades to points)

SELECT c.title, AVG(
  CASE grade WHEN 'A' THEN 4 WHEN 'B' THEN 3 WHEN 'C' THEN 2 WHEN 'D' THEN 1 ELSE 0 END
) AS avg_points
FROM enrollments e
JOIN courses c ON e.course_id = c.course_id
GROUP BY c.title
HAVING AVG(
  CASE grade WHEN 'A' THEN 4 WHEN 'B' THEN 3 WHEN 'C' THEN 2 WHEN 'D' THEN 1 ELSE 0 END
) >= 3.0;

20

SELECT s.name, COUNT(*) AS courses_taken
FROM enrollments e
JOIN students s ON e.student_id = s.student_id
GROUP BY s.name
HAVING COUNT(*) >= 5;

21

SELECT * FROM students
WHERE cgpa > (SELECT AVG(cgpa) FROM students);

22

SELECT c.title
FROM courses c
JOIN enrollments e ON c.course_id = e.course_id
GROUP BY c.course_id, c.title
HAVING COUNT(*) >
 (SELECT AVG(cnt) FROM (
    SELECT COUNT(*) AS cnt
    FROM enrollments
    GROUP BY course_id
 ) t);

23

SELECT s.name
FROM students s
WHERE NOT EXISTS (
  SELECT 1 FROM enrollments e
  WHERE e.student_id = s.student_id AND e.grade = 'F'
);

24

SELECT s.name
FROM students s
JOIN departments d ON s.dept_id = d.dept_id
WHERE NOT EXISTS (
  SELECT 1 FROM courses c
  WHERE c.dept_id = d.dept_id
  AND NOT EXISTS (
    SELECT 1 FROM enrollments e
    WHERE e.student_id = s.student_id AND e.course_id = c.course_id
  )
);

25 (window rank)

SELECT name, dept_id, cgpa,
RANK() OVER (PARTITION BY dept_id ORDER BY cgpa DESC) AS dept_rank
FROM students;

26 (latest per course)

SELECT *
FROM (
  SELECT e.*, ROW_NUMBER() OVER (
    PARTITION BY student_id, course_id ORDER BY semester DESC
  ) AS rn
  FROM enrollments e
) t
WHERE rn = 1;

27

SELECT name, COUNT(*) AS dup_count
FROM students
GROUP BY name
HAVING COUNT(*) > 1;

28 (anti-joins)

SELECT e.*
FROM enrollments e
LEFT JOIN students s ON e.student_id = s.student_id
LEFT JOIN courses  c ON e.course_id  = c.course_id
WHERE s.student_id IS NULL OR c.course_id IS NULL;