有時候 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——這樣超難懂也難 debug。 - 注意效能: PostgreSQL 每次查詢都會重算
VIEW,除非你用MATERIALIZED VIEW。
VIEW 是 PostgreSQL 裡最簡單又好用的工具之一。你不用學新東西,只要換個想法:「這查詢要不要存起來當表用?」如果你的查詢已經很肥很亂——它大概就該變成 VIEW 了。
GO TO FULL VERSION