大家好,我是宁一。
今天讲解SQL教程第18课:子查询。
SQL语句可以嵌套,最常见的就是查询语句的嵌套。
基本语法:
我们一般称外面嵌套的语句为主查询,里面被嵌套的语句为子查询,有时也会叫外查询、内查询,大家知道意思就好。
子查询要用括号括起来。子查询不仅可以放在WHERE的后面,还可以放在SELECT、FROM的后面,我们一个个来讲解。
1、子查询+WHERE子句
SQL执行时,会先执行括号内的子查询,子查询最常与WHERE子句结合使用。子查询的结果作为WHERE子句的筛选条件,完成更复杂的数据检索。
实例: 在Students表中,找出所有在"宁一"后面出生的学生。
实例解析: 需要先确定"宁一"的生日,再将生日作为WHERE筛选条件,得到最终数据。
第一步:找到"宁一"的生日
第二步:将生日作为WHERE筛选条件,得到最终数据,子查询语句要用括号括起来。
SELECT语句的子查询经常与聚合函数结合使用。因为我们使用聚合函数的时候,记录会合成一条,其它数据细节就不能显示了。
比如: 我们想要查看学生表中所有的学生姓名、学生生日、学生的最大生日。
示例结果:
错误写法:
像上面这样写是会报错的,因为聚合函数与其他表中的列(Sname,Sage),同时放在SELECT的后面。需要用GROUP BY语句将这些表中的列(Sname,Sage)分组。
上面的语句后面加上 GROUP BY Sname,Sage 就可以了。
但是这样写,会将每组的数据聚合成1条数据,比如每组有3条数据,使用聚合函数MAX()+GROUP BY,最终每组只会显示1条最大值的数据。
我们需要展现Students表中所有的学生,这样写不能满足我们的需求。
正确写法: 结合子查询来实现。
子查询与FROM子句结合使用,子查询结果被当成了一个“表”,可以用SELECT语句做进一步的筛查。
比如:我们先写一个SELECT查询语句
将上面的查询语句放在FROM的后面,则上面查询到的结果,就会被当成一个“表”。
这里有一个特别要注意的地方,放在FROM后面的子查询,必须要加别名。
复杂的子查询再嵌套进 FROM 里会让整个查询看起来过于复杂,我们一般会将子查询结果储存为视图,然后再直接使用视图作为来源表,视图会SQL高阶课程中详细讲解。
其实子查询就是查询语句嵌套,没有什么新的东西,只是多了一个层级,由内向外地一层层梳理就会很清楚了。
作业: 结合Students表,从Teachers表中找出当班主任的老师(通过子查询实现)。
作业解析: 先从Students表中,找出所有班主任的Tid并去重,将查询结果作为筛选条件,放在WHERE语句中。
首先,应该了解学习SQL对于数据挖掘分析这个工作的重要性;
接下来,应该先学习SQL查询语句的处理和执行过程,以便可以更好的了解到,编写高质量的查询有多重要。具体说来就是,应该了解查询是如何被解析、重写、优化和最终评估的;
掌握了上面一点之后,你不仅需要重温初学者在编写查询语句时,所使用的查询反向模型,而且还需要了解有关可能发生错误的替代方案和解决方案。同时还应该了解更多查询工作中的基于集合的程序方法。
在性能方面也需要关注反向模型,除了手动提高SQL查询的方法外,还需要以更加结构化和深入的方式来分析你的查询,以便使用其它工具来完成整个查询工作。
在执行查询之前,还需要更加深入的了解执行查询计划的时间复杂度。
最后,应该了解如何进一步的调整你的查询语句。
为什么要学SQL?寻找数据挖掘分析行业的工作,SQL是最需要的技能之一,不论是申请数据分析工作、数据引擎工作、数据挖掘分析或者其它工作。在O‘Reilly发布的《2016数据科学从业者薪酬报告》中,有70%的受访者证实了这一点,表示他们需要在专业环境中使用SQL。此外,本次调查中,SQL远胜于R(57%)和Python(54%)等编程语言。所以在数据挖掘分析领域,SQL是必备技能。
我们分析一下SQL从1970s早期开发出,到现在还经久不衰的原因:
一、公司基本都将数据存储在关系数据库管理系统(RDBMS)或关系数据流管理系统(RDSMS)中,所以需要使用SQL来实现访问。SQL是通用的数据语言,可以使用SQL和几乎其它任何数据库进行交互,甚至可以在本地建立自己的数据库!
二、只有少量的SQL实现没有遵循标准,在供应商之间不兼容。因此,了解SQL标准是在数据挖掘分析行业立足的必要要求。
三、最重要的是SQL也被更新的技术所接受,例如Hive或者Spark SQL。Hive是一个用于查询和管理大型数据集的类似于SQL的查询语言界面;Spark SQL可用于执行SQL查询。
简而言之,以下就是为什么你应该学习这种查询语言:
即使对于新手来说,SQL也很容易学习。学习曲线很平缓,编写SQ查询几乎不花费时间。
SQL遵循“学习一次,随时随地可用”的原则,所以花费时间学习SQL很划算!
SQL是对编程语言的一种极好的补充;在某些情况下,编写查询甚至比编写代码更为优先!
SQL处理和查询执行为了提高SQL查询的性能,首先需要知道,运行查询时,内部会发生什么。
以下时查询执行的过程:
首先,将查询解析成“解析树”;分析查询是否满足语法和语义要求。解析器将会创建一个输入查询的内部表示,然后将此输出传递给重写引擎。
然后,优化器的任务是为给定的查询,寻找最佳执行或查询计划。执行计划准确地定义了每个操作所使用的算法,以及如何协调操作的执行。
最后,为了找到最佳的执行计划,优化器会列举所有可能的执行计划,并确定每个计划的质量或成本,以便获取有关当前数据库状态的信息,最后选择最佳的执行计划。由于查询优化器可能不完善,因此数据库用户和管理员有时需要手动检查并调整优化器生成的计划,以便获得更好的性能。
现在你已经清楚了什么才是好的执行计划。
正如前面了解到的,计划的成本质量起着重要的作用。更具体地说,评估计划所需的磁盘I / O数量,计划的CPU花销以及数据库客户端的整体响应时间和总执行时间等因素至关重要。这就是时间复杂性的概念。后面还将继续了解。
接下来,执行所选择的查询计划,由系统的执行引擎进行评估,并返回查询结果。
编写SQL查询需要进一步说明的是,垃圾回收原则(GIGO)原本就是表达在查询处理和执行之中:制定查询的人,同时也决定着SQL查询的性能。
这意味着在编写查询,有些事情可以同步去做。就像文章开始时介绍的,编写查询需要遵循两个标准:首先,编写的查询需要满足一定的标准,其次还应该应对查询中可以出现的性能问题。
总的来说,有四个分句和关键字,方便新手考虑性能问题:
WHERE分句
INNER JOIN和LEFT JOIN关键字
HAVING分句
虽然这种做法简单而天真,但对于一个初学者来说,这些方法却是一个很好的指引。这些地方也是你刚开始编写时,容易发生错误的地方,这些错误也很难发现。
同时,要想提升性能,使其变得有意义,就不能脱离上下文:在考虑SQL性能时,不能武断的认为上面的分句和关键字不好。使用WHERE或HAVING的分句也可能是很好的查询语句。
通过下面的章节来来进一步了解编写查询时反向模型和代替方法,并将这些提示和技巧作为指导。如何重写查询和是否需要重写查询取决于数据量,以及数据库和执行查询所需的次数等。这完全取决于你的查询目标,事先掌握一些有关数据的知识是非常重要的!
1 仅检索你需要的数据在编写SQL查询时,并不是数据越多越好。因此在使用SELECT语句、DISTINCT分句和LIKE操作符时,需要谨慎。
SELECT声明
在编写完查询语句之后,首先需要做的事情就是检查select语句是否简洁。你的目标应该是删除不必要的select列。以便只取到符合你查询目的的数据。
如果还有相关使用exists的子查询,那么就应该在select语句中使用常量,而不是选择实际列的值。当检查实体时,这是特别方便的。
请记住,相关子查询是使用外部查询中的值的子查询,并且在这种情况下,NULL是可以作为“常量”的,这点确实令人困惑!
通过以下示例,可以了解使用常量的含义:
SELECTdriverslicensenr,nameFROMDriversWHEREEXISTS(SELECT‘1‘FROMFinesWHEREfinesdriverslicensenr=driversdriverslicensenr);提示:我们很容易发现,使用相关子查询并不总是一个好主意,所以可以考虑通过以下方式避免使用相关子查询,例如使用INNER JOIN重写:
SELECTdriverslicensenr,nameFROMdriversINNERJOINfinesONfinesdriverslicensenr=driversdriverslicensenr;DISTINCT分句
SELECT DISTINCT语句用于返回不同的值。DISTINCT是一个分句,能不用尽量不用,因为如果将DISTINCT添加到查询语句中,会导致执行时间的增加。
LIKE运算符
在查询中使用LIKE运算符时,如果模式是以%或_开始,则不会使用索引。它将阻止数据库使用索引(如果存在的话)。当然,从另一个角度来看,你也可以认为,这种类型的查询可能会放宽条件,会检索到许多不一定满足查询目标的记录。
另外,你对存储在数据中数据的了解,可以帮助你制定一个模式,使用该模式可以对所有数据进行正确的过滤,以便查找到你最想要的数据。
2 缩小查询结果如果无法避免使用SELECT语句时,可以考虑通过其它方式缩小查询结果。例如,使用LIMIT分句和数据类型转换的方法。
TOP,LIMIT和ROWNUM分句
可以在查询中添加LIMIT或TOP分句,来设置查询结果的最大行数。下面是一个示例:
SELECTTOP3FROMDrivers;请注意,你可以进一步指定PERCENT。
例如,如果你想更改查询的第一行SELECT TOP 50 PERCENT 。
SELECTdriverslicensenr,nameFROMDrivers
LIMIT2;此外,你还可以添加ROWNUM分句,相应于在查询中使用的LIMIT:
SELECTFROMDriversWHEREdriverslicensenr=123456ANDROWNUM<=3;
数据类型转换应该使用最小的数据类型,因为小的数据类型更加有效。
当查询中需要进行数据类型转化,会增加执行时间,所以尽可能的避免数据类型转换的发生;
如果不能避免的话,需要谨慎的定义数据类型的转换。
本文是本系列教程的第一篇,后续还有更多《如何编写更好的SQL查询》的文章分享给大家,敬请期待。
原文链接:http://wwwkdnuggetscom/2017/08/write-better-sql-queries-definitive-guide-part-1html
转载请注明出自:葡萄城控件
本文出自 “葡萄城控件技术团队博客” 博客,请务必保留此出处http://powertoolsteamblog51ctocom/2369428/1960762
如何编写更好的SQL查询:终极指南-第一部分
标签:查询语句sql
列出以下经典SQL教程下载,如果想获得更多更新的SQL教程请到wwwibook8com进入SQL教程列表,更有经典SQL视频教程等着您。01 SQL Server 2000 看图教程 17M 推荐 02 SQL server 2000自学教程 7M 推荐 03 SQL Server 7参考手册 96M 04 SQL Server精华 453M 05 SQL Server 2000数据库开发从零开始 10M 推荐 06 SQL Server 2000数据库管理 16M 07 战胜SQL Server必做练习50题 16M 推荐 08 SQL SERVER 2000培训教程 48M 09 sql server2000实用工具大全 14M 10 SQL基础教程 602M 推荐 11 10分钟学会SQL 324K 12 Microsoft SQL Server7 数据库技术指南 16M 13 Sql Server7教程 39M 14 Microsoft SQL Server高级编程管理指南 75M 15 SQL70教程 1985M 16 SQL Server 2000编程员指南 32M 17 SQL Server 2000数据库开发 13M 18 轻松搞定SQL Server 2000程序设计 10M 19 SQL入门,使用与高级使用篇 55K 20 SQL Server 70 数据库管理与应用开发 2086M 21 SQL Server 2000开发指南 15M 22 SQL_Server_2000编程人员指南 36M 23 SQL Server 2000开发者指南 81M 24 21天学会Sql 21M 25 SQLServer7关系数据库系统管理与开发 143M 26 SQL SERVER 724 学时教程 14M 27 SQL系统管理员新起点--70实用教程 488M 28 sql_server_7编程技术内幕 196M 29 Microsoft SQL Server 管理员手册 6M 30 SQL Server2000 管理手册 94M 31 SQL 2000 简明教程 477M 32 SQL Server 2000 学习教程 105M 33 SQL70最新教程 38M 34 SQL Server 2000菜鸟进阶 408K 连接 http://wwwibook8com/book/sqlhtm
11 运行SQL程序
12 Microsoft Access
13 Microsoft SQL Server
131 SQL Server 2000
132 SQL Server 2005/2008
14 Oracle
15 IBM DB2
16 MySQL
17 PostgreSQL 21 表、列和行
211 表
212 列
213 行
22 主键
23 外键
24 联系
241 一对一
242 一对多
243 多对多
25 规范化
251 第一范式
252 第二范式
253 第三范式
254 其他范式
26 示例数据库
261 表authors
262 表publishers
263 表titles
264 表titles_authors
265 表royalties
27 创建示例数据库 31 SQL语法
32 SQL标准和一致性
33 标识符
34 数据类型
35 字符串类型
36 二进制大型对象类型
37 精确数字类型
38 近似数字类型
39 布尔类型
310 日期和时间类型
311 时间间隔类型
312 唯一标识符
313 其他数据类型
314 空值 41 使用SELECT和FROM检索列
42 使用AS创建列的别名
43 使用DISTINCT消除重复的行
44 使用ORDER BY排序行
45 使用WHERE筛选行
46 使用AND、OR和NOT组合及求反条件
461 AND操作符
462 OR操作符
463 NOT操作符
464 AND、OR和NOT一起使用
47 使用LIKE匹配模式
48 使用BETWEEN进行范围筛选
49 使用IN进行列表筛选
410 使用IS NULL测试空值 51 创建派生列
52 执行算术运算
53 确定计算的顺序
54 使用||连接串
55 使用SUBSTRING()提取子串
56 使用UPPER()和LOWER()更改串的大小写
57 使用TRIM()修整字符
58 使用CHARACTER_LENGTH()得到串长度
59 使用POSITION()查找子串
510 执行日期及时间间隔运算
511 获得当前日期和时间
512 获得用户信息
513 使用CAST()转换数据类型
514 使用CASE计算条件值
515 使用COALESCE()检查空值
516 使用NULLIF()比较表达式 61 使用聚合函数
62 创建聚合表达式
63 使用MIN()查找最小值
64 使用MAX()查找最大值
65 使用SUM()计算总和
66 使用AVG()计算平均值
67 使用COUNT()统计行数
68 使用DISTINCT聚合不重复的值
69 使用GROUP BY分组行
610 使用HAVING筛选分组 71 限定列名
72 使用AS创建表的别名
73 使用联结
74 使用JOIN或WHERE创建联结
75 使用CROSS JOIN创建交叉联结
76 使用NATURAL JOIN创建自然联结
77 使用INNER JOIN创建内联结
78 使用OUTER JOIN创建外联结
79 创建自联结 81 理解子查询
82 子查询语法
83 子查询和联结
84 简单子查询和相关子查询
841 简单子查询
842 相关子查询
85 在子查询中限定列名
86 子查询中的空值
87 使用子查询作为列表达式
88 使用比较操作符比较子查询的值
89 使用IN测试集合成员资格
810 使用ALL比较所有子查询的值
811 使用ANY比较某些子查询的值
812 使用EXISTS检测存在性
813 比较等价查询 91 使用UNION合并行
92 使用INTERSECT查找相同行
93 使用EXCEPT查找不同行 101 显示表结构
102 使用INSERT插入行
103 使用UPDATE更新行
104 使用DELETE删除行 111 创建表
112 理解约束
113 使用CREATE TABLE创建新表
114 使用NOT NULL禁止空值
115 使用DEFAULT确定默认值
116 使用PRIMARY KEY指定主键
117 使用FOREIGN KEY指定外键
118 使用UNIQUE确保值唯一
119 使用CHECK创建检查约束
1110 使用CREATE TEMPORARY TABLE创建临时表
1111 使用CREATE TABLE AS利用已存在表创建新表
1112 使用ALTER TABLE修改表
1113 使用DROP TABLE删除表 121 使用CREATE INDEX创建索引
122 使用DROP INDEX删除索引 131 使用CREATE VIEW创建视图
132 通过视图检索数据
133 通过视图修改数据
1331 通过视图插入行
1332 通过视图更新行
1333 通过视图删除行
134 使用DROP VIEW删除视图 151 动态统计
152 产生序列
153 发现等差数列、递增数列和等值数列
154 限定返回行的数量
1541 Microsoft Access
1542 Microsoft SQL Server
1543 Oracle
1544 IBM DB2
1545 MySQL
1546 PostgreSQL
155 分配排名
156 计算修整均值
157 随机选取行
158 处理重复值
159 创建电话列表
1510 检索元数据
15101 Microsoft Access
15102 Microsoft SQL Server
15103 Oracle
15104 IBM DB2
15105 MySQL
15106 PostgreSQL
1511 处理日期
15111 Microsoft Access
15112 Microsoft SQL Server
15113 Oracle
15114 IBM DB2
15115 MySQL
15116 PostgreSQL
1512 计算中值
1513 查询极值
1514 改变动态统计的中流
1515 旋转结果
1516 处理层次结构
索引
SQL Server实用教程(第2版),仍以当前最流行的Microsoft SQL Server 2000作为平台,分为5个部分,它们分别是:SQL Server(含习题)、客户端/SQL Server 2000开发与编程、SQL Server 2000实验、客户端/SQL Server综合应用实习和附录,比较系统地介绍SQL Server 2000中文版的功能和VB, PB, Delphi, ASP, ASPNET与SQL Server 2000的应用方法。
每一部分均为先讲解后实例,贯穿全书数据库表的结构列于附录中。客户/服务器编程为先讲解后实习,实习内容综合应用了SQL Server 2000的基本功能,比较好地解决了SQL Server 2000学和用的问题。由于本书的内容体系具有自己的特色,并且从方便教和学两个角度组织内容、调试实例和安排先后顺序,所以用本书教和学比较方便。
本书可作为大学本科有关课程的教材,也可供大专、高职学生和广大数据库应用开发人员使用
字符类型
在输入字符数据时应将数据引在单引号内 字符类型也有定长(char[(n)])和变长(varchar[(n)])二种
日期时间类型
分类 datetime和 alldatetime
datetime类型的数据长度为 字节 alldatetime类型的数据长度为 字节
整数型
分类 int allint tinyint int长度为 个字节 allint长度为 个字节 tinyint长度为 字节
精确数值型
分类 decimal[(p[ s])]和numeric[(p[ s])]{p指精度 s指小数位}
近似数值型
分类 float[(n)] real float数据类型可以存储正 负浮点数 n确定二进制数精度 它可以为 到 当其精度为 到 之间时 等同于real数据类型
货币型
分类 money(占 个字节) allmoney(占 个字节)
位数据类型
位数据类型用bit关键字声明 其数据有两种取值 和 在输入 以外的其他值时系统均将它们当作 看待
时间戳数据类型
用timestamp声明
文本和图象类型
文本(text)和图象(image)类型是两种可变长度的数据类型 向text列中插入数据时 应将数据引在单引号内 向image列中插入数据时 应在数据前加 x引导符
标识符
标识符的命名规则如下
( )标识符长度为 到 字符
( )标识符的第一个字符必须为字母或_ @ #符号 其中@和#符号具有特殊的意义 当标识符开头为@时 表示它是一局部变量 标识符首字符为#时 表示是一临时数据库对象 对于表或存储过程 名称开头含一个#号时表示为局部临时对象 含两个##时表示为全局临时对象
( )标识符中第一个字符后面的字符可以为字母 数字或# $ _符号
( )缺省情况下 标识符内不允许有空格 也不允许使用关键字等作为标识符 但可以使用引号来定义特殊标识符
lishixinzhi/Article/program/SQL/201311/16371
欢迎分享,转载请注明来源:品搜搜测评网