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. 【Luogu2900】土地征用(斜率优化,动态规划)

    [Luogu2900]土地征用(斜率优化,动态规划) 题面 Description 农夫John准备扩大他的农场,他正在考虑N (1 <= N <= 50,000) 块长方形的土地. 每块 ...

  2. jQuery中append appendTo prepend prependTo insertBefore insertAfter after before之间的区别

    jQuery中有一个很关键的元素操作,他们的使用方法都一样,但是呈现的结果有所不同. <!DOCTYPE html> <html lang="en"> &l ...

  3. 【转】UML的9种图例解析

    UML图中类之间的关系:依赖,泛化,关联,聚合,组合,实现 类与类图 1) 类(Class)封装了数据和行为,是面向对象的重要组成部分,它是具有相同属性.操作.关系的对象集合的总称. 2) 在系统中, ...

  4. 大数据(3):基于sogou.500w.utf8数据Hbase和Spark实践

    1. HBase安装部署操作 a) 解压HBase安装包tar –zxvf hbase-0.98.0-hadoop2-bin.tar.gzb) 修改环境变量 hbase-env.shexport JA ...

  5. Navicat Premium 11破解补丁下载及安装方法

    Navicat Premium 11.x Patch破解补丁 

  6. Spring源码学习:第1步--在Spring源码中添加最简单的Demo代码

    为了最大程度地贴近Spring源码并进行学习,一种比较直接的做法是:直接在Spring源码中加入Demo代码,并进行调试. 参照以前使用Spring的经验,Spring最简单的使用方法是:一个实体类. ...

  7. 从JavaScript的事件循环到Promise

    JS线程是单线程运行机制,就是自己按顺序做自己的事,浏览器线程用于交互和控制,JS可以操作DOM元素, 说起JS中的异步时,我们需要注意的是,JS中其实有两种异步,一种是基于浏览器的异步IO,比如Aj ...

  8. Python3数据库模块(sqlite3,SQLite3)

    一.sqlite命令 创建数据库:在控制台sqlite3 name .databases     查看数据库 .tables            查看表格名 databaseName .dump & ...

  9. linux下安装软件

    业界的软件标准安装有三步:configure,make,make install,下面是它们的定义: ./configure是用来检测你的安装平台的目标特征的.比如它会检测你是不是有CC或GCC,并不 ...

  10. npm5 packag-lock.json

    前几天升级了 Node.js v8.0 后,自带的 npm 也升级到了5.0,第一次使用的时候确实惊艳到了:原本重新安装一次模块要十几秒到事情,现在一秒多就搞定了.先不要激动,现在我来大概讲一下 np ...