Глава 2. Расчёт динамики ВВП с использованием оконных функций
- О чём эта глава
- Вторая глава РГР: загрузка статистики валового продукта регионов из CSV, выгрузка границ субъектов РФ через QuickOSM, поиск регионов-соседей пространственным предикатом ST_Touches и расчёт динамики показателя «год к году» оконной функцией LAG — с картографической анимацией результата в Time Manager.
- Пререквизиты
- Глава 1 — созданная база региона, навыки QuickOSM и импорта данных. Оконные функции — тема из вопросов к зачёту (№ 19); демонстрация LAG — прямо на этой странице.
- Формат сдачи
- Отчёт присылается в том же файле, что и глава 1 (doc, docx или pdf); GIF-изображение прикладывается к отчёту отдельно.
1. Методические указания (как делать)
- Скачайте данные.
- Откройте QGIS и загрузите данные из CSV-файла:
- Слой → Добавить слой → Добавить слой из текста с разделителями;
- формат файла → Другие разделители → точка с запятой;
- имя слоя → ВВП_Регионы;
- параметры записей — как на картинке; формат геометрии — без геометрии.
- Зайдите в Базы данных → Менеджер БД.
- Раскройте вашу БД и нажмите на public.
- Затем — Импорт слоя/файла.
- Параметры импорта настройте следующим образом:
- С помощью модуля QuickOSM выгрузите административные границы субъектов РФ. Параметры (см. картинку): admin_level = 4, boundary = administrative, в «Россия».
- Удалите лишние слои.
- Удалите лишние атрибуты в admin_level_4_boundary_administrative_Россия. На этом шаге выпишите списком, какие атрибуты оказались лишними!
- Переименуйте слой admin_level_4_boundary_administrative_Россия в Субъекты_РФ.
- Импортируйте слой в БД; параметры на картинке:
- Сделайте запрос к БД и сформируйте список регионов — соседей вашего выбранного региона:
SELECT сосед."name" AS соседний_регион, сосед.geom FROM субъекты_РФ AS основной JOIN субъекты_РФ AS сосед ON ST_Touches(основной.geom, сосед.geom) WHERE основной."name" = 'Ваша область';
- Выгрузите слой и проверьте, все ли регионы-соседи были получены. Ниже пример для Нижегородской области (коричневая) и регионов-соседей (серые):
- Выпишите регионы-соседей списком.
- Соедините таблицы ВВП_Регионы и Субъекты_РФ по названию регионов. В запросе выберите регионы-соседи и ваш регион. Сформируйте статистику изменения динамики ВВП (год к году):
SELECT ВВП_Регионы."object_name" AS регион, субъекты_РФ.geom, ВВП_Регионы."year" AS год, ВВП_Регионы."indicator_value" AS ВВП, ВВП_Регионы."indicator_value" - LAG(ВВП_Регионы."indicator_value") OVER (PARTITION BY ВВП_Регионы."object_name" ORDER BY ВВП_Регионы."year") AS динамика_ВВП FROM ВВП_Регионы JOIN субъекты_РФ ON субъекты_РФ."name" = ВВП_Регионы."object_name" WHERE ВВП_Регионы."object_name" IN ( 'Регион 1', 'Регион 2', 'Регион N' ) ORDER BY ВВП_Регионы."object_name", ВВП_Регионы."year";
Замените список ( 'Регион 1', 'Регион 2', 'Регион N' ) на интересующие вас регионы
плюс ваш выбранный регион. Если в итоговом слое будет не хватать
регионов — проверьте написание регионов в таблицах ВВП_Регионы
и субъекты_РФ.
- Выпишите названия регионов из Субъекты_РФ и вставьте в запрос к таблице ВВП_Регионы. Сравните результат. Например, для Нижегородской области:
SELECT DISTINCT(ВВП_Регионы."object_name") AS регион FROM ВВП_Регионы WHERE ВВП_Регионы."object_name" ILIKE '%Ивановская область%' OR ВВП_Регионы."object_name" ILIKE '%Костромская область%' OR ВВП_Регионы."object_name" ILIKE '%Марий Эл%' OR ВВП_Регионы."object_name" ILIKE '%Чувашия%' OR ВВП_Регионы."object_name" ILIKE '%Мордовия%' OR ВВП_Регионы."object_name" ILIKE '%Владимирская область%' OR ВВП_Регионы."object_name" ILIKE '%Рязанская область%' OR ВВП_Регионы."object_name" ILIKE '%Кировская область%' OR ВВП_Регионы."object_name" ILIKE '%Нижегородская область%' ORDER BY ВВП_Регионы."object_name";
Обратите внимание: для Чувашии ничего не высветится. Почему? Потому что полное название — «Чувашская республика», что не совпадает с запросом.
- Используя результаты запроса, обновите данные в таблице ВВП. Например, для Нижегородской области пришлось переименовать 4 региона:
UPDATE ВВП_Регионы SET "object_name" = CASE WHEN "object_name" = 'Республика Марий Эл' THEN 'Марий Эл' WHEN "object_name" = 'Республика Мордовия' THEN 'Мордовия' WHEN "object_name" = 'Рязанская обл.' THEN 'Рязанская область' WHEN "object_name" = 'Чувашская республика' THEN 'Чувашия' ELSE "object_name" END;
WHEN условие THEN значение;
внутри CASE не бывает WHERE. Вторая частая ловушка — «умные» кавычки из Word
(‘ ’ « ») вместо прямых '': PostgreSQL их не понимает, и запрос падает с синтаксической
ошибкой. Набирайте кавычки в редакторе запросов, а не копируйте из документа.
- Настройте стиль полученного слоя: ПКМ по слою → Стиль → Символизация по диапазонам значений (в старых версиях QGIS — «Градуированный знак») → значение Динамика_ВВП → режим (алгоритм) Равные интервалы → количество классов подбираете самостоятельно, руководствуясь своим эстетическим чувством. Симметричная классификация вокруг 0. Цветовой ряд — как на картинке.
- Не забудьте настроить верную проекцию!
- Используя модуль Time Manager, создайте GIF-изображение с иллюстрацией динамики ВВП.
- Убедитесь, что данные года — в формате Date. Выполните обновление типа столбца (на всякий случай):
Выражение: to_date("Имя столбца с годами", 'yyyy')
2. Демонстрация: как работает LAG() OVER
Оконная функция не сворачивает строки, как агрегат с GROUP BY, а дописывает к каждой
строке значение, вычисленное по её «окну». LAG(x) OVER (PARTITION BY регион
ORDER BY год) берёт значение x из предыдущей строки того же региона
в порядке лет. Нажимайте «шаг»: подсветка показывает окно текущей строки (фиолетовым —
раздел PARTITION, оранжевым — текущая строка), а в колонку «динамика_ВВП» записывается
разность текущего и предыдущего значений.
| регион | год | ВВП | LAG(ВВП) | динамика_ВВП |
|---|
Числа иллюстративные (млрд руб.); порядок обработки строк — как в результате запроса: сортировка по региону, затем по году.
3. Состав отчёта
- Используя файл description_regions_collection_102_v25062024.pdf, дайте описание данных.
- Добавьте цитирование, как указано в файле и соблюдая ГОСТ (ссылка в список используемой литературы).
- Приведите первые 4 строки из CSV-файла и дайте комментарий к каждой приведённой характеристике.
- Покажите запрос для отображения (Листинг 6) всей таблицы с данными ВВП в БД.
- Укажите источник данных для слоя с регионами РФ. Приведите процесс запроса (какой плагин использовался, с какими параметрами).
- Укажите список атрибутов, которые вы удалили из данного слоя.
- Покажите запрос для отображения (Листинг 7) всей таблицы с регионами в БД.
- Приведите запрос из пункта 12 в исправленном виде для вашего варианта (Листинг 8). «Рис. 13. Результат данного запроса».
- Дайте определение оконным функциям и объясните принцип их работы. По пункту 15 сформируйте Листинг 9; на «Рис. 14» приведите результат запроса.
- Если возникли проблемы — приведите список субъектов, которые не вывелись на экран. Укажите причину. Дайте список изменений.
- Покажите настройки стиля слоя и дайте комментарий к нему (что такое симметричная классификация в QGIS и почему «вокруг 0» и проч.). «Рис. 15. Результат применения стиля».
- Расскажите про процесс построения картографической анимации для визуализации динамики изменения ВВП выбранных регионов (какой модуль используете, как настраиваете).
- Дайте результаты анализа (какой из регионов показывает положительную динамику, какой — отрицательную и проч.). GIF-изображение приложите к отчёту.
Контрольные вопросы
-
ST_Touches(a, b) истинен, когда геометрии касаются границами, но их внутренности не пересекаются — это и есть «соседство» регионов. Самосоединение (self join с алиасами «основной» и «сосед») нужно, чтобы сравнить каждый регион с каждым другим в одной таблице Субъекты_РФ.
-
Оконная функция вычисляет значение по набору строк («окну»), определяемому предложением OVER, но не сворачивает строки: каждая строка результата сохраняется и получает своё вычисленное значение. GROUP BY, напротив, заменяет группу строк одной итоговой.
-
PARTITION BY регион делит строки на независимые разделы по регионам; ORDER BY год упорядочивает строки внутри раздела; LAG(v) возвращает значение v из предыдущей строки раздела (для первой строки — NULL). Разность v − LAG(v) даёт изменение показателя «год к году».
-
У первого года региона нет предыдущей строки в разделе, LAG возвращает NULL, а арифметика с NULL даёт NULL. Это корректное поведение: динамика «год к году» для первого наблюдения не определена.
-
ILIKE — регистронезависимый LIKE; шаблон '%Мордовия%' находит строку при любых префиксах («Республика Мордовия»). Ловушка: если официальное название вообще не содержит шаблона (Чувашия ↔ «Чувашская республика»), строка не найдётся — такие случаи исправляются UPDATE … CASE.
-
Границы классов располагаются симметрично относительно нуля (например, −40…−20, −20…0, 0…20, 20…40), а расходящийся цветовой ряд кодирует знак: красные оттенки — спад, синие/зелёные — рост. Так карта честно показывает направление динамики, а не только её величину.
-
Time Manager анимирует слои по колонке с типом даты/времени. Год-число нужно преобразовать в дату выражением to_date("колонка_года", 'yyyy') — тогда модуль сможет листать кадры по годам и собрать GIF динамики ВВП.
Источники
- PostgreSQL 15 Documentation. Window Functions : [сайт]. — URL: https://www.postgresql.org/docs/15/tutorial-window.html (дата обращения: 18.08.2026).
- PostGIS Documentation. ST_Touches : [сайт]. — URL: https://postgis.net/docs/ST_Touches.html (дата обращения: 18.08.2026).
- TimeManager — QGIS Python Plugins Repository : [сайт]. — URL: https://plugins.qgis.org/plugins/timemanager/ (дата обращения: 18.08.2026).