JavaRush /Курсы /SQL SELF /Представления (`VIEW`) в PostgreSQL

Представления (`VIEW`) в PostgreSQL

SQL SELF
13 уровень , 4 лекция
Открыта

Иногда 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
  1. Представление: количество курсов

Это представление считает, сколько курсов у каждого студента:

CREATE VIEW student_course_count AS
SELECT 
    student_id,
    COUNT(*) AS course_count
FROM 
    enrollments
GROUP BY student_id;

Результат:

student_id course_count
1 2
2 2
3 2
  1. Представление: средняя оценка А это — средняя оценка студента (если нет оценки — 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;
  1. Использование этих 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 особенно полезен

  1. Построение отчетов

Один VIEW — одна логика. Вы можете настроить report_enrollments_by_month, report_payments_by_year и т. д.

  1. Разграничение доступа

Создайте VIEW, который показывает только ограниченные данные (например, без персональных данных) и дайте доступ только к нему.

  1. Повторное использование

Вместо того чтобы копировать подзапрос — дайте ему имя в виде VIEW.

Рекомендации

  • Давайте понятные имена: view_avg_scores_by_group, active_users_view — так легче читать.
  • Не делайте цепочки VIEW в VIEW в VIEW — это усложняет понимание и отладку.
  • Следите за производительностью: PostgreSQL будет пересчитывать VIEW при каждом запросе, если это не MATERIALIZED VIEW.

MATERIALIZED VIEW

В отличие от обычного VIEW (который пересчитывается при каждом запросе), MATERIALIZED VIEW физически хранит результат как таблицу. Преимущество — быстрое чтение; недостаток — данные могут устаревать, обновляются командой REFRESH MATERIALIZED VIEW view_name. Используют для тяжёлых аналитических запросов, которые не требуют real-time актуальности.

CREATE MATERIALIZED VIEW heavy_report AS
SELECT student_id, AVG(grade) AS avg_grade
FROM enrollments
GROUP BY student_id;

-- Когда данные устарели:
REFRESH MATERIALIZED VIEW heavy_report;

VIEW — один из самых простых и удобных инструментов в PostgreSQL. Они не требуют новых знаний, только переосмысления: «А может, сохранить этот запрос и использовать как таблицу?» Если ваш запрос становится громоздким — почти наверняка он заслуживает стать VIEW.

2
Задача
SQL SELF, 13 уровень, 4 лекция
Недоступна
Создание простого представления
Создание простого представления
2
Задача
SQL SELF, 13 уровень, 4 лекция
Недоступна
Представление с объединением данных из нескольких таблиц
Представление с объединением данных из нескольких таблиц
1
Опрос
Вложенные SELECT, 13 уровень, 4 лекция
Недоступен
Вложенные SELECT
Вложенные SELECT
Комментарии (10)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
grig_by Уровень 21
11 мая 2026
MATERIALIZED VIEW То чего не было в лекции, но спрашивается в тесте. Материализованное представление (MATERIALIZED VIEW) физически сохраняет результат запроса на диске, в отличие от обычного представления (VIEW), которое является лишь сохранённым SQL-запросом. Оно может периодически обновляться (например, с помощью REFRESH MATERIALIZED VIEW), но не обязательно автоматически при каждом изменении данных.
grig_by Уровень 21
11 мая 2026
Для всех обладающих окр и желающих не перепроходить тест вот результаты. 1. SQL-запросы, которые используются внтури других SQL-запросов. 2. IN. 3. Одно значение. 4. CREATE VIEW. 5. Они позволяют использовать промежуточные результаты для фильтрации данных. 6. Проверяет, что значение не входит в заданный список. 7. EXISTS работает быстрее, останавливаясь при первом совпадении. 8. Они позволяют сохранить сложные запросы и использовать их повторно. 9. Да, если представление обновляемое. 10. Хранит результат выполнения запроса. 11. Одно значение, которое становится частью внешнего запроса. 12. EXISTS. 13. Для проверки отсутствия записей, соотвествующих условию. 14. Результат всегда будет пустым.
Pahoski Ivan Уровень 28
20 марта 2026
Что делает MATERIALIZED VIEW? где это в лекции? в комментариях я так понял никто не отвечает?
Анатолий Уровень 63
29 января 2026
😎
Slevin Уровень 59
5 сентября 2025
Пример из университета Представление: количество курсов Неверно показан "результат". В запросе мы явно выводим ДВЕ колонки.
Ra Уровень 8 Student
25 августа 2025
Из доков: "Активное использование представлений — это ключевой аспект хорошего проектирования баз данных SQL. Представления позволяют вам скрыть внутреннее устройство ваших таблиц, которые могут меняться по мере развития приложения, за надёжными интерфейсами. Представления можно использовать практически везде, где можно использовать обычные таблицы. И довольно часто представления создаются на базе других представлений."
Sergii Kononenko Уровень 1
13 августа 2025
ошибки в контенте! Опять!
Alexandr Уровень 21
7 июля 2025
Что делает MATERIALIZED VIEW? А где это в теме урока!
Sandra Anohina Уровень 60
28 июня 2025
1. Представление: количество курсов. Приведенный в лекции результат не соответствует описанному представлению.
Артем Ювелиров Уровень 15
28 июня 2025
было бы хорошо получать ответы на неверные вопросы в тестах)