Загрузка данных


WITH StudentGrades AS (
    -- 1. Сначала собираем статистику по КАЖДОМУ ученику
    SELECT 
        s.id AS student_id,
        s.class_id,
        MIN(g.grade) AS min_grade, -- Самая плохая оценка ученика
        MAX(g.grade) AS max_grade  -- Самая лучшая оценка
    FROM Students s
    JOIN Grades g ON s.id = g.student_id
    GROUP BY s.id, s.class_id
),
ClassStats AS (
    -- 2. Группируем учеников по классам и считаем категории
    SELECT 
        class_id,
        COUNT(student_id) AS total_students,
        -- Только 5 (Отличники)
        SUM(CASE WHEN min_grade = 5 THEN 1 ELSE 0 END) AS only_5,
        -- Только 4 и 5 (Хорошисты)
        SUM(CASE WHEN min_grade = 4 THEN 1 ELSE 0 END) AS only_4_5,
        -- Есть хотя бы одна 3
        SUM(CASE WHEN min_grade = 3 THEN 1 ELSE 0 END) AS has_3,
        -- Есть хотя бы одна 2
        SUM(CASE WHEN min_grade = 2 THEN 1 ELSE 0 END) AS has_2
    FROM StudentGrades
    GROUP BY class_id
)
-- 3. Выводим итоговый отчет по классам
SELECT 
    c.class_name AS [Класс],
    t.full_name AS [Классный руководитель],
    COALESCE(cs.total_students, 0) AS [Всего учеников],
    COALESCE(ROUND(AVG(CAST(g.grade AS FLOAT)), 2), 0.00) AS [Средний балл],
    COALESCE(cs.only_5, 0) AS [Только на 5],
    COALESCE(cs.only_4_5, 0) AS [Только на 4 и 5],
    COALESCE(cs.has_3, 0) AS [Есть хотя бы одна 3],
    COALESCE(cs.has_2, 0) AS [Есть хотя бы одна 2]
FROM Classes c
LEFT JOIN Teachers t ON c.homeroom_teacher_id = t.id
LEFT JOIN ClassStats cs ON c.id = cs.class_id
LEFT JOIN Students s ON c.id = s.class_id
LEFT JOIN Grades g ON s.id = g.student_id
GROUP BY 
    c.class_name, 
    t.full_name, 
    cs.total_students, 
    cs.only_5, 
    cs.only_4_5, 
    cs.has_3, 
    cs.has_2
ORDER BY c.class_name; -- Порядок от младших к старшим