视图语法:
CREATE VIEW
<view_name> [(column1, column2...)]
AS
SELECT40
<table_name column_names>
FROM
<table_name>
注:
当从视图中创建视图时要仔细,
尽管操作是可以允许的,
但是它使得维护工作变得复杂,
假设你的视图有三级,
如表的视图的视图的视图,
那么当表中的第一级视图被删除时会有什么情况发生?
另外两个视图会仍然存在,
但是在第一个视图恢复之前它们是没有用处的,
切记,
当创建一个视图后,它实际上是一个虚表.
CREATE VIEW
CREDITCARD_DEBTS
AS
SELECT * FROM
DEBTS
WHERE
ACCOUNT_ID = 4;
CREATE VIEW 也允许你从表中选择特定的列到视图中.
CREATE VIEW
COMPANY_INFO (NAME, STATE)
AS
SELECT * FROM
COMPANY;
SELECT * FROM COMPANY_INFO;
注:
用户可以通过创建视图来查询特定的数据,
如果你的表有 50 列且有成千上万个记录,
但是你只需要其中两列的话,
你可以创建视图来选择这两列,
然后从视图中查询.
你会发现查询在数据返回时间上与原来有相当大的不同.
视图继承了已有列的名字,此外视图还可以有自己的名字,SQL 的 CREATE VIEW 允许你对所选择的列进行重命名。
CREATE VIEW
ENVELOPE (COMPANY, MAILING_ADDRESS)
AS
SELECT
NAME,
ADDRESS + " " + CITY + ", " + STATE
FROM COMPANY;
注:
当在视图中使用 SQL 的计算功能时,
SQL会要求你给出一个虚字段的名字,
这是可以理解的,
因为像 COUNT(*)或 AVG(PAYMENT),
是不能作为名字的.
SELECT
BILLS.NAME,
BILLS.AMOUNT,
BANK_ACCOUNTS.BALANCE
BLANCE BANK_ACCOUNTS.BANK BANK
FROM
BILLS,
BANK_ACCOUNTS
WHERE
BILLS.ACCOUNT_ID = BANK_ACCOUNTS.ACCOUNT_ID;
视图表达式:
CREATE VIEW
BILLS_DUE
(
NAME, AMOUNT, ACCT_BALANCE, BANK
)
AS
SELECT
BILLS.NAME,
BILLS.AMOUNT,
BANK_ACCOUNTS.BALANCE
BANK_ACCOUNTS.BANK
FROM
BILLS,
BANK_ACCOUNTS
WHERE
BILLS.ACCOUNT_ID = BANK_ACCOUNTS.ACCOUNT_ID;
如果你对 BILLS_DUE 视图执行查询是使用了一些条件:
SELECT * FROM
BILLS_DUE
WHERE
ACCT_BALANCE > 500;
分析:
SQL 首先查找一个名字叫 BILLS_DUE 的表,
但是没有找到.
SQL 的过程可能会从系统表中发现,
BILLS_DUE 原来是一个视图,
(这依据你所使用的数据库而定)
于是它对视图进行了诠释并形成了如下的查询语句:
SELECT
BILLS.NAME,
BILLS.AMOUNT,
BANK_ACCOUNTS.BALANCE,
BANK_ACCOUNTS.BANK
FROM
BILLS,
BANK_ACCOUNTS
WHERE
BILLS.ACCOUNT_ID = BANK_ACCOUNTS.ACCOUNT_ID
AND
BANK_ACCOUNTS.BALANCE > 500;
eg:
构造一个视图以显示所有需要发送账单的州,
同时要求显示每个州的账单金额总数和账单的总数.
CREATE VIEW
EXAMPLE (STATE, TOTAL_BILLS, TOTAL_AMOUNT)
AS
SELECT
DISTINCT COMPANY.STATE,
COUNT(BILLS.NAME),
SUM(BILLS.AMOUNT)
FROM
BILLS,
COMPANY
GROUP BY
COMPANY.STATE
HAVING
BILLS.NAME = COMPANY.NAME;
eg:
假设你的债权人因为你推迟付款加收 10% 的服务费,
而且不幸的是你在这个月的每件事都需要推迟,
因此你想看一下需要推迟付款的债主的账号.
CREATE VIEW
LATE_PAYMENT
(
NAME, NEW_TOTAL, ACCOUNT_TYPE
)
AS
SELECT
BILLS.NAME,
BILLS.AMOUNT * 1.10,
BANK_ACCOUNTS.TYPE
FROM
BILLS,
BANK_ACCOUNTS
WHERE
BILLS.ACCOUNT_ID = BANK_ACCOUNTS.ACCOUNT_ID;
在视图的 SELECT 语句中使用约束是必然的,
在使用 SELECT 语句中
可以应用下边这两个规则:
1.你不能使用 UNION 操作.
2.你不能使用 ORDER BY 子句,但是在视图中使用
GROUP BY 子句可以有 ORDERBY 子句相同的功能.
CREATE VIEW
LATE_PAYMENT
AS
SELECT * FROM
BILLS;
UPDATE
LATE_PAYMENT
SET
AMOUNT = AMOUNT * 1.10;
UPDATE
LATE_PAYMENT
SET
NEW_TOTAL = NEW_TOTAL + 10
WHERE
NEW_TOTAL > 100;
注:
视图其实就是一组表的映射.
使用视图修改数据会遇到的限制:
1.对于多表视图不能使用 DELETE 语句
2.除非底层表的所有非空列都已经在视图中出现
否则你不能使用 INSERT 语句,
有这个限制的原因是 SQL 不知道应该
将什么数据插入到 NOT COLUMNS 限制列中
(没有在视图中出现的)
3.如果对一个归并的表格插入或更新记录,
那么所有被更新的记录必须属于同一个物理表.
4.如果你在创建视图时使用了 DINTINCT 子句,
那么你就不能插入或更新这个视图中的记录.
5.你不能更新视图中的虚拟列(它是用计算字段得到了)
CREATE VIEW
CANADIAN_BILLS
(NAME, CAN_AMOUNT)
AS
SELECT
NAME,
AMOUNT / 1.10
FROM
BILLS;
分析:
当进行类似这样的单位换算时,
要注意当计算字段创建一个列时修改
底层表的数据时可能带来的问题.
eg:
找出所有发给德克萨斯州的账单金额少于 50 美元的银行的名字
问题拆分:
1.得到所有发给德克萨斯州的账单.
2.找出账单中金额小于 50 美元的记录.
CREATE TABLE
BILLS1
AS
SELECT * FROM
BILLS
WHERE
AMOUNT < 50;
CREATE TABLE
BILLS2 (NAME, AMOUNT, ACCOUNT_ID)
AS
SELECT
BILLS.*
FROM
BILLS,
COMPANY
WHERE
BILLS.NAME = COMPANY.NAME
AND
COMPANY.STATE = "TX";
CREATE VIEW
BILLS3
AS
SELECT * FROM
BILLS2
WHERE
NAME
IN
(
SELECT * FROM
BILLS1
);
CREATE VIEW
BANKS_IN_TEXAS (BANK)
AS
SELECT
BANK_ACCOUNTS.BANK
FROM
BANK_ACCOUNTS,
BILLS3
WHERE
BILLS3.ACCOUNT_ID = BANK_ACCOUNTS.ACCOUNT_ID;
DROP VIEW view_name;
注:
在使用它的时候需要记住 DROP VIEW 命令
会使所有与 DROP 视图相关联的视图不能正常运行
一些数据库系统甚至会将所有
与要 DROP 的视图相关联的视图也删除掉.
你可以删除一个视图而不影响任何一个真实的表
这也就是为什么我们将视图称为虚表的原因
(虚体也使用了相同的逻辑)