Files
LMS/deploy/preflight/groups-courses.sql

125 lines
4.2 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Preflight (до миграций) для перехода на группы-когорты, курсы и перенос лаб/материалов.
-- Только чтение. Запускать на копии рабочей БД до применения миграций.
-- Пример:
-- psql -h localhost -U lms -d lms -f deploy/preflight/groups-courses.sql
\pset pager off
\echo '=== 1. Группы, не подходящие под шаблон ^(.+)-([0-9])([0-9]+)(БО|МО)$ ==='
SELECT id, name
FROM identity.groups
WHERE name !~ '^(.+)-([0-9])([0-9]+)(БО|МО)$'
ORDER BY name;
\echo '=== 2. Разобранные группы с одинаковым кортежем (stream, degree, number, course, enrollment_year) ==='
WITH params AS (
SELECT CASE
WHEN EXTRACT(MONTH FROM now()) >= 9 THEN EXTRACT(YEAR FROM now())
ELSE EXTRACT(YEAR FROM now()) - 1
END::int AS academic_year_start
),
parsed AS (
SELECT
g.name,
m[1] AS stream,
m[2]::int AS course,
m[3]::int AS number,
m[4] AS degree,
(SELECT academic_year_start FROM params) - (m[2]::int - 1) AS enrollment_year
FROM identity.groups g
CROSS JOIN LATERAL (
SELECT regexp_match(g.name, '^(.+)-([0-9])([0-9]+)(БО|МО)$') AS m
) parsed_name
WHERE m IS NOT NULL
)
SELECT stream, degree, number, course, enrollment_year,
count(*) AS groups,
array_agg(name ORDER BY name) AS names
FROM parsed
GROUP BY stream, degree, number, course, enrollment_year
HAVING count(*) > 1
ORDER BY stream, degree, course, number;
\echo '=== 3. Группы, которые не разберутся шаблоном (потребуют ручного разбора) ==='
WITH parsed AS (
SELECT
g.id,
g.name,
m[1] AS stream,
m[2]::int AS course,
m[3]::int AS number,
m[4] AS degree
FROM identity.groups g
CROSS JOIN LATERAL (
SELECT regexp_match(g.name, '^(.+)-([0-9])([0-9]+)(БО|МО)$') AS m
) parsed_name
)
SELECT id, name, stream, course, number, degree
FROM parsed
WHERE stream IS NULL
OR course IS NULL
OR number IS NULL
OR degree IS NULL
ORDER BY name;
\echo '=== 4. Одинаковые имена групп (после снятия UNIQUE станут допустимы) ==='
SELECT name, count(*) AS groups
FROM identity.groups
GROUP BY name
HAVING count(*) > 1
ORDER BY name;
\echo '=== 5. Студенты без текущей группы ==='
SELECT s.student_no, a.login, s.last_name, s.first_name
FROM identity.students s
JOIN identity.accounts a ON a.id = s.account_id
LEFT JOIN identity.enrollments e ON e.student_id = s.account_id
WHERE e.id IS NULL
ORDER BY s.student_no;
\echo '=== 6. Аккаунты по ролям (до появления статусов) ==='
SELECT role, count(*) AS accounts
FROM identity.accounts
GROUP BY role
ORDER BY role;
\echo '=== 7. Дубли номеров лабораторных (все лабы переезжают в один курс C) ==='
SELECT number,
count(*) AS labs,
array_agg(id ORDER BY created_at) AS ids,
array_agg(title ORDER BY created_at) AS titles
FROM academic.labs
GROUP BY number
HAVING count(*) > 1
ORDER BY number;
\echo '=== 8. Лабораторные по семестрам ==='
SELECT semester_id, number, count(*) AS labs
FROM academic.labs
GROUP BY semester_id, number
HAVING count(*) > 1
ORDER BY semester_id, number;
\echo '=== 9. Дубли slug глав (до перехода на частичные индексы) ==='
SELECT slug, count(*) AS chapters
FROM academic.chapters
GROUP BY slug
HAVING count(*) > 1
ORDER BY slug;
\echo '=== 10. Объём материалов ==='
SELECT
(SELECT count(*) FROM academic.chapters) AS chapters,
(SELECT count(*) FROM academic.sections) AS sections,
(SELECT count(*) FROM academic.articles) AS articles,
(SELECT count(*) FROM academic.article_assets) AS article_assets;
\echo '=== 11. Активы без статьи ==='
SELECT count(*) AS assets_without_article
FROM academic.article_assets
WHERE article_id IS NULL;
\echo '=== 12. Семестры ==='
SELECT id, title, year, active
FROM academic.semesters
ORDER BY year, title;