SQL 入门 12:SQL 视图:创建、修改与可更新视图

下面讲 SQL 视图的创建、修改和可更新视图的用法,跟着注释一步步来。

学习内容

  1. 创建视图
  • 用 CREATE VIEW 把查询打包,方便反复用,就像给复杂查询取个名字。
  • 视图不存数据,存的是查询定义,执行时才从基表拉数据。
  • 可以当表查,还能跟其他表连起来用。
  • 修改视图
  • 要改视图?直接删了重来,DROP VIEW 然后 CREATE VIEW。
  • 或者用 CREATE OR REPLACE VIEW,一步到位,省事。
  • 可更新视图
  • 只能基于单表,不能有 JOIN、UNION 这种花里胡哨的操作。
  • 不能用 DISTINCT、GROUP BY、HAVING 或聚合函数(像 SUM、AVG)。
  • SELECT 里不能有子查询。
  • 基表里所有 NOT NULL 列得在视图里(为了支持 INSERT)。
  • 有些视图能直接改基表数据,但得满足条件:
  • 能干啥?可以 UPDATE 或 DELETE 基表数据。
  • WITH CHECK OPTION
  • 视图有筛选条件(比如 WHERE),更新后得确保数据还符合这条件。
  • WITH CHECK OPTION 就像个门卫,拦住不符合条件的更新,防止数据"跑偏"。

示例代码与讲解

1. 创建视图

SELECT

client_id,

name,

SUM(invoice_total) AS total_sales

FROM clients c

JOIN invoices USING (client_id)

GROUP BY client_id, name;

  • 这是个查询,算每个客户的总销售,挺常用的。

CREATE VIEW sales_by_client AS

SELECT

client_id,

name,

SUM(invoice_total) AS total_sales

FROM clients c

JOIN invoices USING (client_id)

GROUP BY client_id, name;

  • 给上面查询包个视图,叫 sales_by_client。跑这代码没输出,但会在数据库里存个视图。像这样:

SELECT *

FROM sales_by_client

ORDER BY total_sales DESC;

  • 直接查视图,销售总额从高到低排。

SELECT *

FROM sales_by_client

JOIN clients USING (client_id);

  • 视图还能跟其他表连,就像普通表一样。

2. 修改视图

DROP VIEW sales_by_client;

  • 视图不想要了?直接删。

CREATE OR REPLACE VIEW client_balance AS

SELECT

client_id,

name,

SUM(invoice_total - payment_total) AS Balance

FROM clients

JOIN invoices USING (client_id)

GROUP BY client_id, name;

  • 改视图直接用 CREATE OR REPLACE,这里搞了个新视图,算客户欠款余额。

3. 可更新视图

CREATE OR REPLACE VIEW invoices_with_balance AS

SELECT

invoice_id,

number,

client_id,

invoice_total,

payment_total,

invoice_total - payment_total AS Balance,

invoice_date,

due_date,

payment_date

FROM invoices

WHERE invoice_total - payment_total > 0;

  • 这个视图列出还没付清的发票(Balance > 0)。
  • 它没用 JOIN、聚合函数啥的,满足可更新条件,能直接改基表数据。

DELETE FROM invoices_with_balance

WHERE invoice_id = 1;

  • 删掉 invoice_id = 1 的发票,基表也跟着变。

UPDATE invoices_with_balance

SET due_date = DATE_ADD(due_date, INTERVAL 2 DAY)

WHERE invoice_id = 2;

  • 把 invoice_id = 2 的截止日期推迟 2 天。

4. WITH CHECK OPTION

UPDATE invoices_with_balance

SET invoice_total = payment_total

WHERE invoice_id = 2;

  • 想把 invoice_id = 2 的 invoice_total 改成 payment_total,结果 Balance 变 0,不符合视图的 Balance > 0,这行就直接没了。

CREATE OR REPLACE VIEW invoices_with_balance1 AS

SELECT

invoice_id,

number,

client_id,

invoice_total,

payment_total,

invoice_total - payment_total AS Balance,

invoice_date,

due_date,

payment_date

FROM invoices

WHERE invoice_total - payment_total > 0

WITH CHECK OPTION;

  • 加上 WITH CHECK OPTION,视图多了一道防线。

UPDATE invoices_with_balance1

SET invoice_total = payment_total

WHERE invoice_id = 3;

  • 再试着改 invoice_id = 3,因为 Balance 会变 0,违反视图条件,直接报错,不让你改。

作业

1. 创建视图

CREATE VIEW client_balance AS

SELECT

client_id,

name,

SUM(invoice_total - payment_total) AS Balance

FROM clients

JOIN invoices USING (client_id)

GROUP BY client_id, name;

  • 搞个视图,算每个客户欠多少钱。

总结

讲了怎么创建视图、改视图,还弄了可更新视图,带上 WITH CHECK OPTION 防跑偏。用的 sql_invoicing 数据库。接下来看存储过程和触发器。

相关推荐
DLYSB_6 分钟前
交换机不会 HTTP 怎么办:用 SNMP Get / Trap 把指标和中断打到博灵声光 TTS
数据库·报警灯
wdfk_prog7 分钟前
canopennode-rtt推荐,不只可以做从站,也可以承担主站角色
c语言·开发语言·数据库·学习·算法·深度优先
几层山下14 分钟前
WPS的word文档转pdf java实现不乱格式生成-已解决
java·pdf·word·wps
昌原的儿子LEO16 分钟前
Linux 网络编程:select 与 epoll IO 多路复用详解
linux·网络·数据库
土星云SaturnCloud18 分钟前
基于土星云边缘计算的园区车辆来访管理AI视觉方案:车牌识别、路线跟踪与卸货区动态分析全流程闭环
服务器·人工智能·ai·边缘计算
Python 实战手记19 分钟前
2026 企业微信主体变更公证办理指南:场景条件、材料清单、线上实操流程
大数据·人工智能·企业微信
草莓熊Lotso22 分钟前
【Redis 初阶】特殊数据类型、渐进式遍历与数据库操作生产指南
linux·网络·数据库·redis·tcp/ip·缓存·bootstrap
CarIise24 分钟前
MySQL数据库与SQL语言:从数据类型到DQL查询核心
sql
λqaq726 分钟前
Redis 数据库基础:安装、5 大核心数据类型与常用命令
linux·数据库·redis·python·缓存
BioRunYiXue26 分钟前
科研干货 | IC50全面解读:概念解析、实验设计与数据分析要点
java·开发语言·javascript·人工智能·算法·数据挖掘·数据分析