SQL 基础知识梳理(五) - 复杂查询

目录

  • 视图
  • 子查询
  • 关联子查询

一、视图

  1.视图和表

    (1)视图:从 SQL 的角度来看视图就是一张表。

    (2)视图和表的区别:是否保存了实际的数据。数据库中的数据实际上保存到计算机的存储设备(如硬盘);视图实际上保存的是 SELECT 语句,从视图中读取数据时,视图会在内部执行该 SELETC 语句并创建出一张临时表。

    (3)视图的优点:

      ①无需保存数据,节省存储设备的容量。

      ②保存频繁使用的 SELECT 语句,提高效率。

  【总结】表中存储的是实际数据,视图保存的是 SELECT 语句。

  【总结】应该将经常使用的 SELECT 语句做成视图。

  

  2.创建视图

--语法
--CREATE VIEW 视图名称(<视图列名1>, <视图列名2>, ...)
--AS
--<SELECT 语句>
--示例:创建视图
CREATE VIEW ShohinSum(shohin_bunrui, cnt_shohin)
AS
SELECT shohin_bunrui, COUNT(*)
FROM dbo.Shohin
GROUP BY shohin_bunrui;
--示例:使用视图
SELECT *
FROM shohinSum;

  视图就是保存好的 SELECT 语句。我们将频繁的查询操作保存成视图,就可以提高效率了。

  

  (1)使用视图的查询

    在FROM 子句中使用视图的查询,通常有如下步骤:

      ①执行定义视图的 SELECT 语句;

      ②根据得到的结果,再执行在 FROM 子句中使用视图的 SELECT 子句。

    也就意味着可能会出现“多重视图”,我们应尽量避免在视图的基础上创建视图,因为这样很可能会降低 SQL 的性能。

  【备注】应避免在视图的基础上创建视图。

  (2)视图的限制 - 创建视图时不能使用 ORDER BY 子句(但可以使用其它 SELECT 子句)

图:假设这是一个新创建的视图

  (3)视图的限制 - 更新视图

图:假设上图去掉 ORDER BY 子句,在成功创建 ShohinSm 视图后,再执行插入时仍然报错

  【备注】通过聚合得到的视图不能进行更新。

  下面是一个成功创建视图并可以执行插入语句的示例。

创建视图并插入

检测数据

  虽然可以对视图实现更新操作,但我们通常不这样做。

  3.删除视图

--语法
--DROP VIEW 视图名称(<视图列名1>, <视图列名2>, ...)
--示例
DROP VIEW shohinSum

二、子查询

  1.子查询和视图:

    (1)子查询:将用来定义视图的 SELECT 语句直接用于 FROM 子句当中。

--示例
SELECT shohin_bunrui, cnt_shohin
FROM
(
SELECT shohin_bunrui, COUNT(*) AS cnt_shohin
FROM Shohin
GROUP BY shohin_bunrui
) AS ShohinSum; --记得加上别名哦

  图中的 AS ShohinSum 是子查询的名称,子查询(subquery)就是“次级(sub)”的“查询(query)”。先执行①的内层查询,再执行②的外层查询。

  【备注】子查询作为内层查询会首先执行。

  子查询的层数没有限制,出于性能和可读性考虑,应避免使用多层嵌套的子查询。

  2.标量子查询

  上面的子查询基本上都会返回多行结果(虽然偶尔只返回 1 行数据),而标量子查询,就是必须而且只能返回 1 行 1 列的结果。

  【备注】标量子查询就是返回单一值的子查询。

--示例:查询出销售单价高于平均销售单价的商品,hanbai_tanka:销售单价
SELECT *
FROM dbo.Shohin
WHERE hanbai_tanka >
(
SELECT AVG(hanbai_tanka)
FROM dbo.Shohin
)

  3.在其它地方书写标量子查询

  能够使用常数或者列名的地方很多:SELECT 子句、GROUP BY 子句、HAVING 子句,或 ORDER BY 子句等。

--示例:在 SELECT 子句中使用标量子查询
SELECT shohin_id ,
shohin_mei ,
hanbai_tanka ,
(
SELECT AVG(hanbai_tanka)
FROM dbo.Shohin
) AS avg_hanbai_tanka FROM dbo.Shohin

  

--示例:在 HAVING 子句中使用标量子查询
SELECT shohin_bunrui,
AVG(hanbai_tanka)
FROM dbo.Shohin
GROUP BY shohin_bunrui
HAVING AVG(hanbai_tanka) >
(
SELECT AVG(hanbai_tanka)
FROM dbo.Shohin
)

  【注意】使用标量子查询时,该子查询不能返回多行结果。

三、关联子查询

  为了直观显示字段名,现在将所有列名都改成中文。

CREATE TABLE Shohin
(
商品编号 CHAR(4) NOT NULL,
商品名称 VARCHAR(100) NOT NULL,
商品分类 VARCHAR(32) NOT NULL,
销售单价 INTEGER ,
进货单价 INTEGER ,
登记日期 DATE ,
PRIMARY KEY (商品编号)
); INSERT INTO Shohin VALUES ('', 'T恤' ,'衣服', 1000, 500, '2009-09-20');
INSERT INTO Shohin VALUES ('', '打孔器', '办公用品', 500, 320, '2009-09-11');
INSERT INTO Shohin VALUES ('', '运动T恤', '衣服', 4000, 2800, NULL);
INSERT INTO Shohin VALUES ('', '菜刀', '厨房用具', 3000, 2800, '2009-09-20');
INSERT INTO Shohin VALUES ('', '高压锅', '厨房用具', 6800, 5000, '2009-01-15');
INSERT INTO Shohin VALUES ('', '叉子', '厨房用具', 500, NULL, '2009-09-20');
INSERT INTO Shohin VALUES ('', '擦菜板', '厨房用具', 880, 790, '2008-04-28');
INSERT INTO Shohin VALUES ('', '圆珠笔', '办公用品', 100, NULL, '2009-11-11');

建表语句:CREATE TABLE Shohin

  1.普通子查询和关联子查询的区别

  思考:选取出各商品分类中高于该分类平均销售单价的商品?

图 因为内部的子查询不是前一节中的标量子查询(这里返回三行结果),所以报错

  【备注】在 WHERE 子句中使用子查询时,该子查询的结果必须为单一值。

--正确的语句:采用关联子查询
SELECT *
FROM dbo.Shohin s1
WHERE 销售单价 >
(
SELECT AVG(s2.销售单价) AS avg_销售单价
FROM dbo.Shohin s2
WHERE s1.商品分类 = s2.商品分类
GROUP BY s2.商品分类
)

  图

  关键作用的语句:在子查询中添加的 WHERE 子句的条件。该条件的意思是:在同种商品中对个商品的销售单价和平均销售单价作比较。

  

  2.结合条件一定要写在子查询 

  图:把关联条件移到子查询之外

  这里涉及到关联名称的作用域。子查询内部设定的关联名称,只能在该子查询内部使用。也可以这样说:“内部可以看到外部,而外部看不到内部”。

备注

  这里采用 MS SQL Server 进行验证,不保证所有的 DBMS 执行结果正确。

《SQL 基础知识梳理》系列

  《SQL 基础知识梳理(一) - 数据库与 SQL

  《SQL 基础知识梳理(二) - 查询基础

  《SQL 基础知识梳理(三) - 聚合和排序

  《SQL 基础知识梳理(四) - 数据更新

  《SQL 基础知识梳理(五) - 复杂查询

  《SQL 基础知识梳理(六)- 函数、谓词、CASE 表达式

  《SQL 基础知识梳理(七)- 集合运算


【博主】反骨仔

【原文】http://www.cnblogs.com/liqingwen/p/5939796.html

【参考】《SQL ゼロからはじめるデータベース操作》

[SQL] SQL 基础知识梳理(五) - 复杂查询的更多相关文章

  1. 【SQL】- 基础知识梳理(二) - SQL简介

    一.引言 在梳理这些知识之前,说实话,如果有人问我SQL是什么?我可能会回答就是“INSERT,DELETE,UPDATE,SELECT”语句呗,还能是啥. 二.SQL概念 SQL是什么? SQL是S ...

  2. 【SQL】- 基础知识梳理(三) - SQL连接查询

    一.引言 有时为了得到一张报表的完整数据,需要从两个或更多的表中获取结果,这时就用到了"连接查询". 二.连接查询 连接查询的定义: 数据库中的表通过键将彼此联系起来,从而获取这些 ...

  3. 【SQL】- 基础知识梳理(五) - 触发器

    触发器的概念 触发器对表进行插入.更新.删除的时候会自动执行的特殊存储过程 触发器的语法 create trigger tgr_name on table_name with encrypion –加 ...

  4. 【SQL】- 基础知识梳理(四) - 存储过程

    存储过程的概念 存储过程Procedure是一组为了完成特定功能的SQL语句集合,经编译后存储在数据库中,用户通过指定存储过程的名称并给出参数来执行 存储过程的好处 A. 存储过程允许标准组件式编程  ...

  5. 【SQL】- 基础知识梳理(六) - 游标

    游标的概念 结果集,结果集就是select查询之后返回的所有行数据的集合. 游标(Cursor): 是处理数据的一种方法. 它可以定位到结果集中的某一行,对数据进行读写. 也可以移动游标定位到你需要的 ...

  6. 【SQL】- 基础知识梳理(八) - 事务与锁

    事务的概念 事务:若干条T-SQL指令组成的一个操作数据库的最小执行单元,这个整体要么全部成功,要么全部失败.(并发控制) 事务的四个属性:原子性.一致性.隔离性.持久性.称为事务的ACID特性. 原 ...

  7. 【SQL】- 基础知识梳理(七) - 索引

    索引的概念 在关系型数据库中,索引是对数据库表中一列或多列的值进行排序的一种结构. SQL SERVER中有索引的类型:按存储结构区分:“聚集索引(又称聚类索引,簇集索引)”,“分聚集索引(非聚类索引 ...

  8. 【SQL】- 基础知识梳理(一) - 数据库

    一.引言 知识分享这个事情在公司会议上被提出过几次,可一直因各种事情耽搁下来,“我不如地狱,谁入地狱”,怀着这样一种心态,写下了 数据库系列知识分享. 本文将一步步通过循序渐进的方式带你去了解数据库. ...

  9. [SQL] SQL 基础知识梳理(二) - 查询基础

    SQL 基础知识梳理(二) - 查询基础 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5904824.html 序 这是<SQL 基础知识梳理( ...

随机推荐

  1. 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑

    阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...

  2. java head space/ java.lang.OutOfMemoryError: Java heap space内存溢出

    上一篇JMX/JConsole调试本地还可以在centos6.5 服务器上进行监控有个问题端口只开放22那么设置的9998端口 你怎么都连不上怎么监控?(如果大神知道还望指点,个人见解) 线上项目出现 ...

  3. Mac OS 使用 Vagrant 管理虚拟机(VirtualBox)

    Vagrant(官网.github)是一款构建虚拟开发环境的工具,支持 Window,Linux,Mac OS,Vagrant 中的 Boxes 概念类似于 Docker(实质是不同的),你可以把它看 ...

  4. CSS 3学习——transform 2D转换

    首先声明一点,transform属性不为none的元素是它的定位子元素(绝对定位和固定定位)的包含块,而且对内创建一个新的层叠上下文. 注意:可以通过 transform-box 属性指定元素的那个盒 ...

  5. Loadrunner Http Json接口压力测试

    前天接到了一个测试任务,要求测试一下ES(elsticsearch)在不同并发下的查询效率.如图: 业务场景是在客户端根据具体车牌查询相关车辆信息,结果返回前10条记录. 从图中可以看到,接口的请求参 ...

  6. 自己实现简单Spring Ioc

    IoC则是一种 软件设计模式,简单来说Spring通过工厂+反射来实现IoC. 原理简单说明: 其实就是通过解析xml文件,通过反射创建出我们所需要的bean,再将这些bean挨个放到集合中,然后对外 ...

  7. JS高级前端开发群加群说明及如何晋级

    JS高级前端开发群加群说明 一.文章背景: 二. 高级群: 三. 加入方式: 四. 说明:   一.文章背景: 去年年初建了几个群,在不经意间火了,一直排在“前端开发”关键字搜索结果第一名.当然取得这 ...

  8. XSS 前端防火墙 —— 可疑模块拦截

    上一篇介绍的系统,已能预警现实中的大多数 XSS 攻击,但想绕过还是很容易的. 由于是在前端防护,策略配置都能在源代码里找到,因此很快就能试出破解方案.并且攻击者可以屏蔽日志接口,在自己电脑上永不发出 ...

  9. 你从未知道如此强大的ASP.NET MVC DefaultModelBinder

    看到很多ASP.NET MVC项目还在从request.querystring或者formContext里面获取数据,这实在是非常落后的做法.也有的项目建了大量的自定义的modelbinder,以为很 ...

  10. 论C#之多继承

    C#多继承的讨论似乎是个古老的问题了,但今天本文要向大家展示的C#多继承可能是大家闻所未闻见所未见的,甚至是发明C#语言的人也不曾想到我会这样去写代码,并且自得其乐. 说起多继承,首先大家可以想想这个 ...