• SQL基础学习_04_视图


    视图

    1. 视图的创建

        视图就是保存好的SELECT语句,这些SELECT语句执行之后会产生新的表,所以在SQL中,视图和表是不做差别对待的,也就是SQL也可以对视图做一些操作;

        由于视图并不实际保存数据,只是保存了执行的SELECT语句,可以节约存储空间,但是对于大数据量的存储,使用视图来频繁操作的话,势必会占用较大的计算时间,也算是一种用时间换空间的方案。

        通过以下语句创建视图:

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

        如:

        CREATE VIEW ShohinSum(shohin_bunrui, cnt_shohin)
        AS
        SELECT shohin_bunrui, COUNT(*)
        FROM Shohin
        GROUP BY shohin_bunrui;

        此时,如果执行:

        show tables;

        可以看到多了一张ShohinSum的表,对该表可以进行一般查询,但是并不能插入和修改数据,可更新的视图需要满足一定的条件;

    2. 多重视图

        由于视图在SQL中也是一张表,所以也可以在视图的基础上再创建视图,可想而知,这样做会使得SQL的效率变得很慢

    3. 视图定义的限制

        1. 不能使用ORDER BY子句定义(除了PostgreSQL,但是也应该尽量避免)

        2. 对视图进行更新的条件:

            1. SELECT子句中未使用DISTINCT

            2. FROM子句中只有一张表

            3. 未使用GROUP BY子句

            4. 未使用HAVING子句 

            能不能更新一个视图,最终还是要看响应的操作能不能在原表中也做响应的修改,如果原表可以同时进行更新,则视图就可以更新;

            而在PostgreSQL中,视图默认是只读的,如果要在可更新的视图中做更新操作,需要做以下操作:

            CREATE  OR REPLACE RULE insert_rule
            AS ON INSERT
            TO <视图名> DO INSTEAD

    4. 删除视图

        通过DROP VIEW来删除视图

    子查询

    1. 定义

        子查询就是一张一次性的视图,由于视图可以当成表的特性,在FROM子句中,可以用小括号将视图作为一个表来处理:

        SELECT <列1>,<列2>,…
        FROM (SELECT 语句) AS  <子查询名>

        子查询在执行时,先执行被当成视图的SELECT语句,然后再执行外层查询语句;

        可以嵌套多个子查询,但是相应的性能也会变差;

    2. 标量子查询

        标量子查询就是返回单一值的子查询,由于返回的是单一值,所以可以使用比较运算等各种运算中。

        标量子查询的一个应用就是使得WHERE 语句中使用聚合函数的返回值,如:

        SELECT shohin_id, shohin_mei, hanbai_tanka
        FROM Shohin
        WHERE hanbai_tanka > (SELECT AVG(hanbai_tanka) FROM Shohin); 

        由于先执行视图中的SELECT语句,并且返回一个标量,所以在WHERE中并不会产生错误,解决WHERE子句不能使用聚合函数的问题;

        标量子查询也可以应用在现实标量值的查询中,如:

        SELECT shohin_id, shohin_mei, hanbai_tanka, (SELECT AVG(hanbai_tanka) FROM Shohin) AS avg_tanka
        FROM Shohin; 

    3. 关联子查询

        标量子查询用起来非常方便,但是如果返回的值并不是标量,而是有多个值的时候,就不能简单地做比较以及其他的标量操作,

        通过使用关联子查询,可以解决这个问题。

        关联子查询实际上就是设定一个限制条件,使得视图中的查询返回的结果是唯一适用于外层查询的;

        如果将子查询看成是一个二重循环,关联子查询实际上就是在内层循环中添加一个条件,使得只返回一个值,并且该值是外层循环需要的,

        比较难用文字解释,看示例:

        SELECT shohin_id, shohin_mei, hanbai_tanka
        FROM Shohin AS S1
        WHERE hanbai_tanka > (SELECT AVG(hanbai_tanka)
                                                 FROM Shohin AS S2
                                                 WHERE S1.shohin_bunrui = S2.shohin_bunrui
                                                 GROUP BY shohin_bunrui);

        由于上面的子查询中使用到了GROUP BY,所以该子查询会返回多个值,此时使用比较运算发生错误;

        关联子查询的关键就是添加WHERE S1.shohin_bunrui = S2.shohin_bunrui 子句,该子句使得子查询只返回一个值,并且该值和外层查询同组,也就是外层查询需要的值,

        通过关联子查询巧妙地解决子查询多个返回值的比较运算问题;

        通过上述的查询语句,可以看出名称的作用域的关系,S1在内外两层中都可以被使用,但是S2只有子查询中才能被看到;按照二重循环的理解,这一点是显而易见的。

  • 相关阅读:
    mac 卸载 node并重新安装
    最小的Django应用
    Python如何实现文本转语音
    Python语言库pyttsx3
    大数据资料
    剑指offer(29)最小的K个数
    剑指offer(28)数组中出现次数超过一半的数
    剑指offer(27)字符串的排列
    剑指offer(26)二叉搜索树与双向链表
    JS、JAVA刷题和C刷题的一个很重要的区别
  • 原文地址:https://www.cnblogs.com/lyon2014/p/4678643.html
Copyright © 2020-2023  润新知