1.视图(View)

我们知道,在关系型数据库中,用来保存实际数据记录的是数据表。和表同等概念也是用来保存东西是:视图。

但是数据表是用来保存实际数据记录的,而视图是用来保存常用select语句的。

一个视图保存一条select语句。

使用视图的好处:

1.节省存储空间:

一般情况,如果我们希望将某条select语句的执行的结果表保存起来,我们就需要新建一张表,将结果表的数据记录保存在我们新建的这张表中。

这样,如果是少量数据还好,但是如果面对的大量的数据,这样势必会耗费去大量的存储空间。

如果选用视图,我们利用一个视图来保存这条select语句。当我们需要使用这条select语句执行之后的结果表的数据记录时,我们可以选取这个视图中

的select语句进行执行,执行之后就会形成一张保存了数据记录的临时表。

2.不用重新书写常用select语句

将常用的select语句保存为视图,我们在使用时,就可以不用每次都书写相同的select语句。其实这时候,就相当于我们将常用的select语句拷贝出来,

保存在我们本地的文本文件中,一个文本文件保存一个select语句,在使用的时候,找到相应的文本文件,进行执行。这个文本文件就是视图。

所以我们应该将常用的select语句保存在视图中。

创建视图的方法:

创建视图需要使用create view语句 ,基本语法格式:

create  view   <视图名>   (<视图列名1>,<视图列名2>,......)   as   <select语句>;

(<视图列名1>,<视图列名2>,......)称为视图列名清单。

这里的视图列名相当于给后面的select语句中的列 起的别名。所以视图列名应该和select语句中的列名 进行一一对应。如果select语句中已经为列名指定了

别名,不需要再指定相同功能的视图列名,可以省略视图列名清单。

使用视图进行查询:

select  <列名1>,<列名2>,......  from   <视图名>;

这里from子句选择了视图,就相当于执行了该视图中的select语句,得到了一张保存了数据记录的结果表。

前面的select子句再在结果表中选出哪几列来进行显示,形成新的结果表。如果显示结果表的全部列,则使用 select  * 。

由此可见,选取一条视图,至少执行了2次的select语句。

关于多重视图:

我们可以在一个视图保存的select语句,该select语句又选取了另一个视图。这样嵌套,形成了多重视图。

但是由于多重视图的可阅读性不好,建议不要使用。

视图的限制:

1.在视图保存的select语句中不能使用order by子句进行排序

该select语句可以使用 where子句,group by子句,having 子句。但是不能使用order by子句。

2.利用视图来增加,删除,更新原表数据记录

我们知道可以利用视图中保存的select语句,结合select语句来进行 使用视图进行查询。初次之外,我们还可以利用视图中保存的select语句,集合insert语句,

delete语句,update语句 ,来实现 利用视图来进行原表数据的增,删,改操作。

insert  into  <视图名>  values  (<值1>,<值2>,......);

但是 利用视图中保存的select语句 来实现增,删,改要保证 通过视图保存的select语句查询出来的结果表没有进行聚合操作(group by ,聚合函数等)。否则,

对于结果表的增,删,改操作,将无法与原表中的数据进行同步,破坏了数据的一致性。

比较有代表性的几个条件是:

select子句中不能使用distinct来去重;

from子句中只能有一张表;

不能使用group  by子句;

不能使用having子句;

不能使用聚合函数;

删除视图:

删除视图需要用到drop view语句。基本语句格式是:

drop  view  <视图名>;

2.子查询

子查询就是将保存在视图中的select语句用于from子句中。如下格式:

select   ......   from   (select   .....  from .....)  as   <子查询结果表的别名>;

其实子查询 和 视图的作用过程都是一样的 。 先通过写在后面的 select语句 进行查询得到一张子查询结果表,为该表起一个别名。

然后在通过前面的select语句对子查询结果表进行查询,形成最终的结果表。

需要注意的一点是:默认我们都需要为 查询出来的子查询结果表起一个别名。在其他数据库中需要使用as,在oracle数据库中为表起别名,

不能使用as。

select   ......   from   (select   .....  from .....)   <子查询结果表的别名>;

如果在子查询中再嵌套子查询,就形成了多层嵌套的子查询。 但是随着子查询嵌套层数的增加,SQL语句就变得越来越难读懂,而且执行

效率会下降。所以应该避免使用多层的嵌套子查询。

标量子查询:

标量子查询区别于普通子查询的是 :普通子查询 形成的结果表是保存有若干条记录的表。 标量子查询 形成的结果是一个数值。(也可看成是一行一列的一条记录)

标量子查询就是返回单一值的子查询。

由于标量子查询返回的是一个数值,所以在可以使用数值的子句中,均可以使用标量子查询。

select  .....   from  ......   where   age  <=  (select  avg(age)  from  tb_person);

select avg(age)  from tb_person;子查询返回的是单一的数值,属于标量子查询。

3.关联子查询

关联子查询会在细分的组内进行比较时使用。

分析一种查询情况,根据学生的班级对学生进行分组,计算每个班级的平均总分,让后筛选出总分高于他所在班级平均总分的学生。

由于是分组内进行比较,需要使用关联子查询。

select  t2.name  , t2.score  from  tb_student as  t2  where  t2.score   >=  (select  avg(score)  from  tb_student  as  t1  where   t2.classId  =  t1.classId  group  by  t1.classId);

可以看出通过

select  avg(score)  from  tb_student  as  t1   group  by  t1.classId;

这个普通子查询,我们会得到N个班级的平均总分的一张表,表有N行记录。

但是这时前面的where子句  where t2.score >= ?  显然需要一个标量值进行比较,也就是需要一个标量子查询的结果。
这时在子查询中添加  的  where t2.classId = t1.classId    这样where子句 把每条记录的总分与 select子查询生成的结果表的总分 进行了一对一的关联。

也就是要比较一个学生的总分和平均总分的大小,先根据该学生的classId  在子查询生成的结果表中 找到这个班级的平均总分,然后再比较。

结合条件一定要写在子查询中。这是因为关联名称的作用域。

子查询中的可以使用 外层查询的关联名称  t1

但是外层查询不能使用 子查询的关联名称  t2

DML数据操作语言之复杂查询的更多相关文章

  1. 6.1课堂笔记—DML(数据操作语言),DQL查询语句

    一.DML(数据操作语言) InnoDB MyISAM 支持事务 不支持事务 不支持全文索引 支持全文索引 支持外键约束 不支持 命令查看默认存储引擎 show variables like '%st ...

  2. DML数据操作语言

    DML数据操作语言 用来对数据库中表的数据记录进行更新.(增删改) 插入insert -- insert into 表(列名1,列名2,列名3...) values (值1,值2,值3...):向表中 ...

  3. DML数据操作语言之增加,删除,更新

    1.数据的增加 数据的增加要用到insert语句  ,基本格式是: insert into <表名> (列名1,列名2,列名3,......) values (值1,值2,值3,..... ...

  4. DML数据操作语言之查询(二)

    当我们查询出了N条记录之后 ,我们知道一共是几条记录,或者这些记录某一字段(列值)的最大值,最小值,平均值等,就可以使用聚合函数. 1.聚合函数 聚合函数会将null 排除在外.但是count(*)例 ...

  5. DML数据操作语言之查询(一)

    1.select语句基础 基本语句格式:  select <列名>,.... from <表名>; select子句中列举出希望从表中查询出的列的名称,from子句则指定了选取 ...

  6. DML数据操作语言之谓词,case表达式

    谓词:就是返回值是真值的函数. 前面接触到的“>” “<” “=”等称为比较运算符,它们的正式名称就是比较谓词.因为它们比较之后返回的结果是真值. 由于谓词 返回的结果是一个真值 ,即tr ...

  7. DML数据操作语言之常用函数

    所谓函数,就是输入某一值,得到相应的输出结果的功能.相当于一个加工厂,给了原料,最终产出成品. 其中原料 就是参数(parameter). 产品 就是返回值. 函数大致可以分为以下五个种类: 算术函数 ...

  8. MySQL SQL DML (数据操作语言)

    包括 SELECT, UPDATE, DELETE, INSERT SELECT 从数据库表中获取数据 用法 SELECT name FROM students; SELECT name,age FR ...

  9. DML数据操作语言练习

    --创建表T_HQ_BM2 --create table t_hq_bm2 as select * from t_hq_bm; commit; --添加行内容 --insert into t_hq_b ...

随机推荐

  1. 【洛谷2744 】【CJOJ1804】[USACO5.3]量取牛奶Milk Measuring

    题面 Description 农夫约翰要量取 Q(1 <= Q <= 20,000)夸脱(夸脱,quarts,容积单位--译者注) 他的最好的牛奶,并把它装入一个大瓶子中卖出.消费者要多少 ...

  2. 【BZOJ2734】【HNOI2012】集合选数(状态压缩,动态规划)

    [BZOJ2734][HNOI2012]集合选数(状态压缩,动态规划) 题面 Description <集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所 ...

  3. PHP 秒数 转时分秒 函数

    function secondsToHour($seconds){ if(intval($seconds) < 60) $tt ="00时00分".sprintf(" ...

  4. linux 添加ftp用户与登录配置详解

    不同类Unix有一定区别 版本不同也有些区别 在linux主机上如何添加ftp用户 (一)修改配置文件 vi /etc/vsftpd/vsftpd.conf 在96行,97,98行 96 chroot ...

  5. php 目录处理函数

    之前我们处理的全都是文件,那目录和文件夹怎么处理呢? 我们就来学习目录或者称为文件夹的处理相关函数. 处理文件夹的基本思想如下: 1.读取某个路径的时候判断是否是文件夹 2.是文件夹的话,打开指定文件 ...

  6. C#枚举数值与名称的转换实例分享

    首先建立一个枚举: 复制代码代码如下: /// <summary>    /// 颜色    /// </summary>    public enum ColorType   ...

  7. 如何实现vue前端跨域,proxyTable解决开发环境前端跨域问题

    在开发环境与后端调试的时候难免会遇到跨域问题,很多人说跨域交给后端解决就好了. 其实不然,前端也有很多方法可以解决跨域,方便也快捷. 常见的有nginx转发.node代理. 在vue项目中常用的是pr ...

  8. .Net小白的大学四年,内含面经

    大家好 我是码农阿宇,和博客园的广大兄弟一样,我们都喜欢.Net,但是你们是985/211,而我江西一所普通得不能再普通的二本大学---九江学院,大四毕业在即,英语四级未过(为什么强调这一点?见文末- ...

  9. eclipse的Debug模式下的快捷键

    主要快捷键: F5, F6, F7, F8的使用 F5:  进入当前方法 F6: 一步步执行 F7:  跳出方法, 返回到调用此方法的最后一条语句 F8: 继续执行,跳转到下一个断点的位置 示例: 在 ...

  10. 兄弟连学Python-3Python变量和数据类型

    变量:变量就是可以改变的量.如:x+y = 10 x=5 , y=? x=7 , y=? 这是数学里的变量 通俗的理解:变量     =   生活中的容器(盒子) 变量的赋值操作  =  我们把物品放 ...