Иногда SQL-запросы становятся слишком большими, сложными и повторяющимися. Например, вы строите отчёт по студентам с их средними оценками и количеством курсов — и пишете один и тот же подзапрос в пяти местах. Чтобы не копировать одно и то же снова и снова, используйте представления — или VIEW.
VIEW — это как “сохранённый запрос”, которому можно дать имя и обращаться к нему как к таблице. Он не хранит данные, а лишь структуру запроса.
Это особенно полезно, когда вы хотите:
- упростить читаемость SQL-кода;
- повторно использовать сложную выборку;
- скрыть технические детали от пользователей;
- разграничить уровни доступа (показывать только нужные данные).
Как работает VIEW?
Создать представление — значит создать псевдотаблицу на основе SELECT-запроса. Например:
CREATE VIEW student_avg_grades AS
SELECT
s.student_id,
s.name,
AVG(g.grade) AS avg_grade
FROM
students s
JOIN
grades g ON s.student_id = g.student_id
GROUP BY
s.student_id, s.name;
Теперь можно обращаться к student_avg_grades как к обычной таблице:
SELECT * FROM student_avg_grades WHERE avg_grade > 4.5;
Пример из университета
Вы часто анализируете студентов, их курсы и оценки. Представим, что нужно построить сводный отчёт по каждому студенту:
- имя,
- количество записей на курсы,
- средняя оценка.
Если попытаться сделать это одним махом — получится длинный и неудобочитаемый SQL. Гораздо удобнее разбить задачу: сначала создадим два представления (VIEW), а потом объединим их.
Таблица students
| id | name |
|---|---|
| 1 | Alex Lin |
| 2 | Anna Song |
| 3 | Maria Chi |
| 4 | Dan Seth |
Таблица enrollments
| student_id | course_id | grade |
|---|---|---|
| 1 | 1 | 90 |
| 1 | 2 | 85 |
| 2 | 2 | 88 |
| 2 | 3 | 91 |
| 3 | 1 | 75 |
| 3 | 3 | NULL |
- Представление: количество курсов
Это представление считает, сколько курсов у каждого студента:
CREATE VIEW student_course_count AS
SELECT
student_id,
COUNT(*) AS course_count
FROM
enrollments
GROUP BY student_id;
Результат:
| name |
|---|
| Alex Lin |
| Anna Song |
| Maria Chi |
- Представление: средняя оценка А это — средняя оценка студента (если нет оценки — NULL, и она не влияет):
CREATE VIEW student_avg_grade AS
SELECT
student_id,
AVG(grade) AS avg_grade
FROM
enrollments
WHERE grade IS NOT NULL
GROUP BY student_id;
- Использование этих
VIEW
SELECT
s.name,
c.course_count,
a.avg_grade
FROM
students s
LEFT JOIN student_course_count c ON s.student_id = c.student_id
LEFT JOIN student_avg_grade a ON s.student_id = a.student_id;
Теперь у вас чистый и понятный запрос. А самое главное — его легко поддерживать.
Обновляемость VIEW
Представления обычно не содержат данных — это просто "обёртка" над запросом. Однако, можно использовать их даже для обновления данных, если VIEW удовлетворяет нескольким условиям (например, без JOIN, GROUP BY, агрегатов и подзапросов).
Пример обновляемого представления:
CREATE VIEW active_students AS
SELECT * FROM students WHERE active = true;
Теперь можно выполнять:
UPDATE active_students SET name = 'Иван Петров' WHERE student_id = 2;
Но если VIEW сложный (например, содержит JOIN или GROUP BY), он становится только для чтения. Для обновлений можно использовать INSTEAD OF триггеры, но это уже продвинутый уровень.
Как удалить или изменить VIEW
Удаление:
DROP VIEW student_avg_grade;
Обновление:
CREATE OR REPLACE VIEW student_avg_grade AS
SELECT student_id, ROUND(AVG(grade), 2) AS avg_grade
FROM grades
GROUP BY student_id;
Примеры: когда VIEW особенно полезен
- Построение отчетов
Один VIEW — одна логика. Вы можете настроить report_enrollments_by_month, report_payments_by_year и т. д.
- Разграничение доступа
Создайте VIEW, который показывает только ограниченные данные (например, без персональных данных) и дайте доступ только к нему.
- Повторное использование
Вместо того чтобы копировать подзапрос — дайте ему имя в виде VIEW.
Рекомендации
- Давайте понятные имена:
view_avg_scores_by_group,active_users_view— так легче читать. - Не делайте цепочки
VIEWвVIEWвVIEW— это усложняет понимание и отладку. - Следите за производительностью: PostgreSQL будет пересчитывать
VIEWпри каждом запросе, если это неMATERIALIZED VIEW.
VIEW — один из самых простых и удобных инструментов в PostgreSQL. Они не требуют новых знаний, только переосмысления: «А может, сохранить этот запрос и использовать как таблицу?» Если ваш запрос становится громоздким — почти наверняка он заслуживает стать VIEW.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ