视图

表里面保存的是实际数据,视图里面保存的是SELECT语句(视图本身不存储数据)。

从视图中读取数据,此时视图在内部执行SELECT语句,创建一张临时表。

使用视图的好处:其一,视图不保存数据,节省存储设备容量。其二,将频繁使用的SELECT语句保存成视图,每次使用这些语句时候,不用重复书写,只需调用视图。其三,数据保存到表中,要显式的执行SQL更新语句才能更新数据,而视图中的数据会随着原表的变化自动更新。

创建视图

格式:

CREATE VIEW 视图名称(<视图列名1>,<视图列名2>,...)
AS
<SELECT语句>

例子:

CREATE VIEW ProductSum (product_type, cnt_product)
AS
SELECT product_type, COUNT(*)FROM ProductGROUP BY product_type;

使用视图

可见,如果使用视图,不用每次都写GROUP BY等一些语句从Product表中取数据。

并且,如果Product表中数据更新,视图也自动更新。

这是因为,视图就是保存好的SELECT语句。

SELECT product_type, cnt_productFROM ProductSum;

多重视图:以视图为基础创建视图。但是这样会降低SQL性能。

CREATE VIEW ProductSumA (product_type, cnt_product)
AS
SELECT product_type, cnt_productFROM ProductSumWHERE product_type = '办公用品';

定义视图时,不能用ORDER BY子句。因为视图和表,数据行都没有顺序。

(PostgreSQL里面,定义视图时候可以用ORDER BY子句,有些DBMS不行)

视图更新:

如果定义视图的SELECT语句满足一些条件,视图可以被更新。

SELECT子句没用DISTINCT、FROM子句只有一张表、没用GROUP BY、没用HAVING。

通过汇总得到的数据无法更新,这是因为视图和表要同时更新。

如果给上面的ProductSum中添加(‘食物’,3)的数据,原表就需要增加三行种类为食物的数据,但是这些数据我们都不知道,因此没法更新表中的数据。

可以更新下面这样,不通过汇总得到的视图。

CREATE VIEW ProductA (product_id, product_name, product_type, sale_price, purchase_price, regist_date)
AS
SELECT *FROM ProductWHERE product_type = '办公用品';

向视图插入数据。

INSERT INTO ProductA VALUES ('0009', '铅笔', '办公用品', 95, 10, '2222-10-1');

此时可看到,视图和表都更新了。

删除视图:

格式

DROP VIEW 视图名称(<视图列名1>,<视图列名2>,...)

例子

DROP VIEW ProductSum;

然后报错

ERROR:  cannot drop view productsum because other objects depend on it
描述:  view productsuma depends on view productsum
提示:  Use DROP ... CASCADE to drop the dependent objects too.

这是因为前面以ProductSum为基础,创建了一个ProductSumA视图。

可以像下面这样删除ProductSum和与之关联的视图。

DROP VIEW ProductSum CASCADE;

子查询

子查询,相当于一次性视图。

定义视图ProductSum

CREATE VIEW ProductSum (product_type, cnt_product)
AS
SELECT product_type, COUNT(*)FROM ProductGROUP BY product_type;

子查询:将定义视图的SELECT语句直接用到FROM子句里面。

AS ProductSum,ProductSum是子查询的名称。执行完外边的SELECT语句,子查询就消失了。

下面代码,执行顺序,先是FROM子句里面的SELECT语句,然后是外边的SELECT语句。

SELECT product_type, cnt_productFROM (SELECT product_type, COUNT(*) AS cnt_productFROM ProductGROUP BY product_type) AS ProductSum;

下面再次查看ProductSum发现,ProductSum已经不存在了。由此看出,子查询是一次性的,并不像视图一样保存到硬盘里面。

在子查询的FROM子句里面,可以继续使用子查询。

下面就是把ProductSum里面cnt_product = 4的数据选出来了。

SELECT product_type, cnt_productFROM (SELECT *FROM (SELECT product_type, COUNT(*) AS cnt_productFROM ProductGROUP BY product_type) AS ProductSumWHERE cnt_product = 4) AS ProductSum2;

标量子查询scalar subquery,返回表中某一行某一列的值(单一值)的子查询。

可以在WHERE子句中使用标量子查询。

由于WHERE子句中无法使用聚合函数,像下面的语句就是错误的。

SELECT product_id, product_name, sale_priceFROM ProductWHERE sale_price > AVG(sale_price);

可以通过下面这样去实现。

SELECT product_id, product_name, sale_priceFROM ProductWHERE sale_price > (SELECT AVG(sale_price)FROM Product);

在任何使用单一值的地方,都可以使用标量子查询。

在SELECT子句中使用标量子查询:

SELECT product_id, product_name, sale_price,(SELECT AVG(sale_price)FROM Product) AS avg_priceFROM Product;

在HAVING子句中使用标量子查询:

不同商品种类的平均销售单价与全部商品的销售单价相比。

SELECT product_type, AVG(sale_price)FROM ProductGROUP BY product_type
HAVING AVG(sale_price) > (SELECT AVG(sale_price)FROM Product);

标量子查询不能返回多行结果,如果返回多行结果,那就是一个普通的子查询,不能用到需要单一输入值的地方了。

关联子查询

现在要选取各个商品种类里面,高于该商品种类平均销售价的商品。

按照商品种类计算平均价格:

SELECT AVG(sale_price)FROM ProductGROUP BY product_type;

因为有三种商品,上面这个查询返回三个结果。

那么就不能用下面这种方法了。因为子查询不是标量子查询,不能在WHERE子句里面用。

SELECT product_id, product_name, sale_priceFROM ProductWHERE sale_price > (SELECT AVG(sale_price)FROM ProductGROUP BY product_type);

在细分的组内进行比较的时候,用到关联子查询。

在子查询里面添加了一个WHERE子句。目的是在同一商品种类中对各商品销售单价和平均单价比较。

由于比较对象是同一个Product表,所以用了P1、P2两个别名。

使用关联子查询,用<表名>.<列名>形式,限定product_type,对平均单价比较。

SELECT product_type, product_name, sale_priceFROM Product AS P1WHERE sale_price > (SELECT AVG(sale_price)FROM Product AS P2WHERE P1.product_type = P2.product_typeGROUP BY product_type);

而且,不加GROUP BY,也能得到相同结果:

SELECT product_type, product_name, sale_priceFROM Product AS P1WHERE sale_price > (SELECT AVG(sale_price)FROM Product AS P2WHERE P1.product_type = P2.product_type);

PostgreSQL 视图、子查询相关推荐

  1. 什么是 PostgreSQL 横向子查询?

    作者 | 不剪发的Tony老师   责编 | 晋兆雨 出品 | CSDN博客 一般来说,SQL 子查询只能引用外查询中的字段,而不能使用同一层级中其他表中的字段.例如: -- 错误示例 SELECT ...

  2. 【SQL】(task3)复杂查询(视图 | 子查询 | 谓词 | Case)

    学习总结 (1)视图和子查询.对于一些复杂的查询需要使用子查询加一些条件语句组合才能得到正确的结果.一个SQL语句的层数不能过深,不然可读性差而且执行效率也难以保证,所以尽量有简洁的语句来完成需要的功 ...

  3. mysql视图子查询_mysql创建视图不能包涵子查询的解决办法。View's SELECT contains a subquery in the FROM clause...

    如下查询是没问题,但要创建成视图就报View's SELECT contains a subquery in the FROM clause错误. CREATE or REPLACE VIEW `v_ ...

  4. order by 子查询_视图,子查询,标量子查询,关联子查询

    视图 子查询 标量子查询 关联子查询 如何用SQL解决业务问题 各种函数 1. 视图 视图内存放SQL查询语句,运行时运行该语句.查出的数据为临时数据 创建视图 create view as 视图名称 ...

  5. select子查询多个字段_SQL复杂查询

    一.视图 视图是虚拟的表.与包含数据的表不一样,视图只包含使用时动态检索数据的查询. 优点: • 重用SQL语句. • 简化复杂的SQL操作.在编写查询后,可以方便地重用它而不必知道其基本查询细节. ...

  6. 【转】ORACLE中的子查询 ---OCP--047--46

    "子查询"就是查询中嵌套着另一个查询,也即通过SELECT语句的嵌套使用形成子查询.当我们不知道特定的查询条件时,可以用子查询来为父查询提供查询条件以获得查询结果. ORACLE中 ...

  7. power bulider 9.0 如何将sql语句查询的值返回给变量_SQL—你应该知道的子查询

    (本文结合<SQL基础教程>整理) 文章结构 视图 子查询 变量子查询 关联子查询 如何用SQL解决业务问题 常见函数 视图 视图的定义: 视图究竟是什么呢?如果用一句话概述的话,就是&q ...

  8. 各种SQL子查询实例

    返回订单表中订单价值超过5000美元的那些客户的详细信息. SELECT * FROM customers WHERE cust_id IN (SELECT DISTINCT cust_id FROM ...

  9. sql 子查询及基本语句 挺全的收录

    引自https://blog.csdn.net/jia_gugang/article/details/80282873 一.SQL子查询语句 1.单行子查询         select ename, ...

最新文章

  1. python 非线性回归_机器学习入门之菜鸟之路——机器学习之非线性回归个人理解及python实现...
  2. 读《三体Ⅱ · 黑暗森林》| 人能相互理解的前提是力量对等
  3. 年少成名的我并没有放弃自己,谁敢说她\他文章比我写的好?!,不服来战!...
  4. (五)Struts2 标签
  5. 异常值处理 - iterrows()对 DataFrame 进行遍历,并修改遍历中的异常值 - Python代码
  6. Windows 7样式地址栏(Address Bar)控件实现
  7. java与C#对比文章阅读
  8. java并发编程(3)避免活跃性危险
  9. Eclipse或者MyEclipse—在Eclipse或MyEclipse中的操作(3)
  10. java程序开发的流程_Java程序开发流程(图文解说版)
  11. 第九届蓝桥杯c语言b组试题+部分答案
  12. nRF51 SDK 例程分析——Blinky Example
  13. 小四哥的故事——访中联绿盟陈庆
  14. UI设计中线面结合图标设计总结
  15. 期货交易在使用基本面分析操作过程中要注意哪些问题?怎么控制风险?
  16. 临门一脚 | 技术水平一般的程序员如何准备面试
  17. 数学之美-读书笔记6-10章
  18. 如何提取视频中的音频,不需要软件,在线就能做到
  19. Java 中的 Swing 框架现在是不是被淘汰了?
  20. H264编码- 码率控制 RQ 模型参数推导过程以及JM代码分析

热门文章

  1. mybatisPlus中的field-strategy(字段更新插入策略):null值插入和更新问题
  2. 35-46集 中心极限定理、置信区间
  3. 明令禁止工作“996”,是对“生而为人”的基本尊重
  4. java js websocket_js+java websocket记录
  5. matlab 判断鼠标按下_轻巧可爱,支持多设备——雷柏Ralemo Air1乐萌鼠标
  6. 怎么格式化电脑_U盘格式化后数据能恢复吗?人人都能学会的恢复方法!
  7. python io操作有什么_Python笔记:文件IO操作
  8. c++new时赋初值_C高级编程精髓之内存管理,万千码农踩过的雷,大神带你走出雷区...
  9. php ouput buffer,Redis配置详解-客户端缓冲区 output buffer
  10. 搜狐视频怎么开启青少年模式