8. SQL——视图

视图

        • 1. 使用视图
        • 2. 列的重命名
        • 3. SQL 对视图的处理过程
        • 4. 在 SELECT 语句中使用约束
        • 5. 在视图中修改数据
        • 6. 在单位换算中使用视图
        • 7. 在视图上使用简单的结构化复合查询
        • 8. 删除视图语句

1. 使用视图


视图语法:

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 列且有成千上万个记录,
但是你只需要其中两列的话,
你可以创建视图来选择这两列,
然后从视图中查询.

你会发现查询在数据返回时间上与原来有相当大的不同.


2. 列的重命名

视图继承了已有列的名字,此外视图还可以有自己的名字,SQL 的 CREATE VIEW 允许你对所选择的列进行重命名。


CREATE VIEW 
ENVELOPE (COMPANY, MAILING_ADDRESS) 
AS
SELECT 
NAME, 
ADDRESS + " " + CITY + ", " + STATE
FROM COMPANY;


注:
当在视图中使用 SQL 的计算功能时,
SQL会要求你给出一个虚字段的名字,
这是可以理解的,
因为像 COUNT(*)AVG(PAYMENT),
是不能作为名字的.


3. SQL 对视图的处理过程


 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;
 

4. 在 SELECT 语句中使用约束


在视图的 SELECT 语句中使用约束是必然的,
在使用 SELECT 语句中
可以应用下边这两个规则:

1.你不能使用 UNION 操作.

2.你不能使用 ORDER BY 子句,但是在视图中使用 
GROUP BY 子句可以有 ORDERBY 子句相同的功能.


5. 在视图中修改数据


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.你不能更新视图中的虚拟列(它是用计算字段得到了)


6. 在单位换算中使用视图


CREATE VIEW 
CANADIAN_BILLS 
(NAME, CAN_AMOUNT) 
AS
SELECT 
NAME, 
AMOUNT / 1.10
FROM 
BILLS;

分析:
当进行类似这样的单位换算时,
要注意当计算字段创建一个列时修改
底层表的数据时可能带来的问题.


7. 在视图上使用简单的结构化复合查询


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;


8. 删除视图语句


DROP VIEW view_name;

注:
在使用它的时候需要记住 DROP VIEW 命令
会使所有与 DROP 视图相关联的视图不能正常运行 
一些数据库系统甚至会将所有
与要 DROP 的视图相关联的视图也删除掉.

你可以删除一个视图而不影响任何一个真实的表 
这也就是为什么我们将视图称为虚表的原因 
(虚体也使用了相同的逻辑)

你可能感兴趣的:(SQL学习分享)