设为首页 收藏本站
查看: 1120|回复: 0

[经验分享] [SQL] SQL 基础知识梳理(五)

[复制链接]

尚未签到

发表于 2017-7-14 13:37:27 | 显示全部楼层 |阅读模式
SQL 基础知识梳理(五) - 复杂查询
   DSC0000.png

目录


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

一、视图
  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;
DSC0001.png

DSC0002.png

  视图就是保存好的 SELECT 语句。我们将频繁的查询操作保存成视图,就可以提高效率了。
  (1)使用视图的查询
  在FROM 子句中使用视图的查询,通常有如下步骤:
  ①执行定义视图的 SELECT 语句;
  ②根据得到的结果,再执行在 FROM 子句中使用视图的 SELECT 子句。
  也就意味着可能会出现“多重视图”,我们应尽量避免在视图的基础上创建视图,因为这样很可能会降低 SQL 的性能。
  【备注】应避免在视图的基础上创建视图。
  (2)视图的限制 - 创建视图时不能使用 ORDER BY 子句(但可以使用其它 SELECT 子句)
DSC0003.png

  图:假设这是一个新创建的视图
  (3)视图的限制 - 更新视图
DSC0004.png

  图:假设上图去掉 ORDER BY 子句,在成功创建 ShohinSm 视图后,再执行插入时仍然报错
  【备注】通过聚合得到的视图不能进行更新。
  下面是一个成功创建视图并可以执行插入语句的示例。
DSC0005.png

  创建视图并插入 DSC0006.png
  检测数据
  虽然可以对视图实现更新操作,但我们通常不这样做。
  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;    --记得加上别名哦
DSC0007.png

DSC0008.png

  图中的 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
)
DSC0009.png

DSC00010.png

  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
DSC00011.png




--示例:在 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
)
DSC00012.png

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


三、关联子查询
  为了直观显示字段名,现在将所有列名都改成中文。


DSC00014.gif DSC00015.gif


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

  1.普通子查询和关联子查询的区别
  思考:选取出各商品分类中高于该分类平均销售单价的商品?
DSC00017.png

  图
DSC00018.png

  图 因为内部的子查询不是前一节中的标量子查询(这里返回三行结果),所以报错
  【备注】在 WHERE 子句中使用子查询时,该子查询的结果必须为单一值。



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

  图
  关键作用的语句:在子查询中添加的 WHERE 子句的条件。该条件的意思是:在同种商品中对个商品的销售单价和平均销售单价作比较。
  2.结合条件一定要写在子查询 
DSC00020.png

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

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

《SQL 基础知识梳理》系列
  《SQL 基础知识梳理(一) - 数据库与 SQL》
  《SQL 基础知识梳理(二) - 查询基础》
  《SQL 基础知识梳理(三) - 聚合和排序》
  《SQL 基础知识梳理(四) - 数据更新》
  《SQL 基础知识梳理(五) - 复杂查询》
  《SQL 基础知识梳理(六)- 函数、谓词、CASE 表达式》
  《SQL 基础知识梳理(七)- 集合运算》

  【博主】反骨仔
  【原文】http://www.cnblogs.com/liqingwen/p/5939796.html
  【参考】《SQL ゼロからはじめるデータベース操作》

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-393754-1-1.html 上篇帖子: SQL Server 中怎么查看一个字母的ascii编码或者Unicode编码 下篇帖子: SQL语句的优化建议
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表