SqlServer
T-SQL
示例数据库:点我
- Chapter 01 T-SQL 查询和编程背景
- 1.3 创建表和定义数据的完整性
- 1.3.1 创建表
- 1.3.2 定义数据的完整性
- 1. 主键约束
- 2. 唯一约束
- 3. 外键束约
- 4. CHECK约束
- 5. 默认约束
- Chapter 02 单表查询
- 2.1 SELECT 语句元素
- 2.1.7 TOP和OFFSET-FETCH
- 1. TOP筛选
- 2. OFFSET-FETCH
- 2.1.8 开窗函数速览
- 2.2 谓词和运算符
- 2.3 CASE表达式
- 2.5 同时操作
- 2.6 运算符和函数
- 2.6.1 字符串连接(+和CONCAT函数)
- 2.6.2 SUBSTRING 函数
- 2.6.3 LEFT 和 RIGHT函数
- 2.6.4 LEN 和 DATALENGTH 函数
- 2.6.5 CHARINDEX 函数
- 2.6.6 PATINDEX 函数
- 2.6.7 REPLACE 函数
- 2.6.8 REPLICATE 函数
- 2.6.9 STUFF 函数
- 2.6.10 UPPER 和 LOWER 函数
- 2.6.11 RTRIM 和 LRITM 函数
- 2.6.12 FORMAT 函数
- 2.6.13 LIKE 谓词
- 2.7 时间和日期
- 2.7.1 当前时间
- 2.7.2 CAST、CONVERT和PARSE函数,及其TRY_对应函数
- 2.7.3 SWITCHOFFSET 函数
- 2.7.4 TODATETIMEOFFSET 函数
- 2.7.5 DATEADD 函数
- 2.7.6 DATEDIFF 函数
- 2.7.7 DATEPART 、YEAR、MONTH、DAY和DATENAME 函数
- 2.7.7 ISDATE 函数
- 2.7.8 FORMPARTS 函数
- 2.7.9 EOMONTH 函数
- 2.8 查询元数据
- 2.8.1 目录视图
- 2.8.2 信息架构视图
- 2.8.3 系统存储过程和函数
- 81.jpg
- 练习
- CHAPTER 03 联接
- 3.1交叉联接
- 3.1.1 ANSI SQL-92 和 89 语法
- 3.1.2 自交叉联接
- 3.1.3 生成数字表
- 3.2 内部联接
- 3.2.1 ANSI SQL-92、89 语法和安全性
- 3.3 更多联接示例
- 3.3.1 复合联接
- 3.3.2 不等联接
- 3.3.3 多联接查询
- 3.4 外部联接
- 3.4.1 外联接基础知识
- 3.4.2 其他外联接知识
- 练习
- CHAPTER 04 子查询
- 4.1 自包含子查询
- 4.1.1 自包含标量子查询示例
- 4.1.2 自包含多值子查询示例
- 4.2 相关子查询
- 4.2.1 EXISTS 谓词
- 4.3 额外子查询知识
- 4.3.1 返回前一个或下一个值
- 4.3.2 使用运行聚合
- 4.3.3 不当子查询处理
- 4.3.3.1 NULL故障
- 4.3.2 子查询列中的替换错误
- 练习
1.3.1 创建表
在创建对象脚本中包含语句是十分重要,能确保在指定的数据库中创建对象。
1.3.2 定义数据的完整性
1. 主键约束
主键约束强制行的唯一性,在约束的属性中不允许使用标记。约束的属性的值必须是唯一的,每个表只能有一个主键。为了强制逻辑主键约束的一唯一性,SQL Server会在后台创建一个唯一索引。唯一索引是SQL Server为了强制唯一性所使用的一种物理机制。
2. 唯一约束
唯一约束强制行的唯一性,允许你在自己的数据库中实现关系模型的备用键概念。与主键不同,可以在同一个表内定义多个唯一约束,此外,唯一约束不限制列必须定义为。根据SQL标准,具有唯一约束的列应该允许重复的值。但是,SQL Server则不允许重复的标记
3. 外键束约
外键用于强制引用的完整性,此约束定义了引用表中的一个或多个属性指向被引用表(父表)中候选键(主键或唯一约束),引用表和被引用表可以是同一个。外键的目的是限制在外键列中允许的值要存在于那些被引用列中。
如果表中的订单引用了中的某一个雇员行,当尝试从中删除这一雇员行时,RDBMS会拒绝删除并抛出错误。
4. CHECK约束
CHECK允许定义一个谓词,确保进入到表中的行或是被修改的行必须满足些约束。
5. 默认约束
如果没有在插入时指定一个显式值时,将会使用该默认值。
SELECT语句的查询顺序:
- FROM
- WHERE
- GROUP BY
- HAVING
- SELECT
- ORDER BY
2.1.7 TOP和OFFSET-FETCH
1. TOP筛选
指定10个最近的订单:
可以为选项指定关键字,向上舍入。
我们可以发现,在前4行的数据中,orderdate是相相同的,在这种没有指定决胜属性(tiebreaker)的情况下,对具有相同值的orderdate排序是没有意义的。SQL Server返回的结果是不确定的,即哪行先被物理访问到就先返回哪行。
如果希望查询结果是确定的,则需要列出的数据是唯一的,即要添加一个决胜发展(tiebreaker)。如可在加入orderid作为
或者使用作为关联行,来实现tiebreaker
注意,即使指定了TOP 5,但是输出却是8行。SQL Server首先返回基于orderdate DESC排序的TOP 5行,然后是返回与检索到的5行中最后一行orderdate值相同的其他所有行。
2. OFFSET-FETCH
TOP不是标准SQL,并且不支持跳过功能。标准的SQL定义的TOP类似筛选称为为OFFSET-FETCH,支持跳过功能。SQL SERVER 2012中的OFFSET-FETCH被视为ORDER BY子句的一部分,通常用于实现按顺序
显示效果。子句指定要跳过的行数,子句指定在跳过的行数后要筛选的行数。
基于排序好的结果,子句跳过行,由FETCH子句往后取行。
注意,使用OFFSET-FETCH的查询必须具有ORDER BY子句。此外FETCH子句不支持没有OFFSET子句。不过,没有FETCH的OFFSET是允许的,这种情况就是跳过多少行,并返回剩余的所有行。而且ROW和ROWS是可以互换的。
2.1.8 开窗函数速览
开窗函数的功能是:对于基本的每一行,按行的窗口(组)进行运算,并计算一个标量(单个)结果值,行的窗口使用OVER子句定义。OVER子句可以使用PARTITION BY子子句约束窗口中的行,并且可以使用ORDER BY子子名为计算结果定义排序。
ROW_NUMBER函数对于查询结果按custid进行分区,并在各个分区内按照指定的val进行排序,分配了唯一、递增、连续的整数。
注意,ROW_NUMBER函数必须在每个分区内生成唯一值 。这意味着即使排序值不增加,行号也会增加。
SELECT列表中的表达式是在DISTINCT子句之前计算的,总之,sql语句的执行顺序为:
- FROM
- WHERE
- GROUP BY
- HAVING
- SELECT
- 表达式
- DISTINCT
- ORDER BY
- TOP/OFFSET-FETCH
CASE是一个标题表达式,返回一个基于条件置逻辑的值。注意,CASE是表达式而不是语句。所以,它不支持你控制活动流或是做一些基于条件逻辑的损伤。可以在诸如:、、和 子句中以及在中使用。具有简单和复杂格式,ELSE子句默认值为NULL
格式:
格式:
T-SQL 中某些函数可以看作是CASE的表达式缩写,如:ISNULL、COALESCE、IIF和CHOOSE,其中只有COALESCE*是标准的,后两个仅在2012版本中可以使用
这是一个col2/col1大于2的查询语句,很有可能假定SQL Server 会从左到右计算此表达式。从而使得col=0时会出现短路,从而不继续进行col2/col1的计算。但是,SQL Server 支持短路,这是基于SQL标准的同时操作概念。SQL Server通常基于成本估计来进行表达式的计算顺序。所以此语句有可能会查询失败。对于此种特定情况,该语句可改写为
2.6.1 字符串连接(+和CONCAT函数)
使用*+CONVERT*,CAST将转换为,否则可能会因不能转换为类型而报错,这是因为SQL Server会隐式的将其他转换为。
2.6.2 SUBSTRING 函数
SUBSTRING(string, start, length) 在sql中,字符串下标从1开始算起,而不是0。
2.6.3 LEFT 和 RIGHT函数
LEFT(string, n),RIGHT(string, n),n代表从LEFT或RIGHT提取的字符数
2.6.4 LEN 和 DATALENGTH 函数
2.6.5 CHARINDEX 函数
CHARINDEX(subString, string[,start_pos]) 返回字符串从开始在中第一次出现的位置。如果找不到指定的字符串,返回0
2.6.6 PATINDEX 函数
PATINDEX(pattern,string) 与
2.6.7 REPLACE 函数
REPLACE(string, subString1, subString2) 使用取代中所有的
2.6.8 REPLICATE 函数
REPLICATE(string, n) 将复制次
2.6.9 STUFF 函数
STUFF(string, pos, del_length, insertString) 从位置开始,删除指定长度的字符串,并从处插入字符串
2.6.10 UPPER 和 LOWER 函数
返回大小写或小写字符串
2.6.11 RTRIM 和 LRITM 函数
从右边或左边删句末或句首的空格
2.6.12 FORMAT 函数
FORMAT(input, format_string, culture) 按照.NET格式和一个可选的区域参数,将格式化成一个字符串 从位置开始,删除指定长度的字符串,并从处插入字符串
2.6.13 LIKE 谓词
- 通配符,代表单个字符必须是指定
- 内的字符之一
- 字符,要查找上面定义的通配符时,需要使用转义字符。如要查找
- :
- 或
在筛选列上应用操作时,数据库不能以有效方式使用索引,所以如果要筛选日期范围时可使用如来代替
2.7.1 当前时间
2.7.2 CAST、CONVERT和PARSE函数,及其TRY_对应函数
输入值如果转换成功,则返回目标值,否则就会查询失败。其对应的 TRY_ 函数执行的是相同的操作,只是如果查询失败返回的是 NULL 。
语法:
CAST(val AS datatype)
CONVERT(dataType, val [,sytle_number])
PARSE(val AS dataType [USING culture])
2.7.3 SWITCHOFFSET 函数
SEITCHOFFSET(datatimeoffset_val, time_zone) 该函数将输入的值调整为指定的时区
2.7.4 TODATETIMEOFFSET 函数
TODATETIMEOFFSET(date_and_time_value,time_zone) 设置为时区,通常用于迁移非已知偏移量数据到已知偏移数据。
2.7.5 DATEADD 函数
DATEADD(part,n,dt_val) 指定日期的某个部分part增加n到dt_val中
- part:
- ,也可以使用缩写形式,如yy代替year等
- n:可以是正、负数
2.7.6 DATEDIFF 函数
DATEDIFF(part, dt_val1, dt_val2) 返回 到 之间指定日期部分 part 的间隔
2.7.7 DATEPART 、YEAR、MONTH、DAY和DATENAME 函数
DATEPART(part, dt_val) 返回 指定日期部分 的值。可以使用 YEAR(),MONTH(),DAY() 代替
DATETIME(part, dt_val) 此函数和
2.7.7 ISDATE 函数
ISDATE(string) 判断 string 是否为日期格式可以转换为日期格式数据,可以则返回,否则返回。
2.7.8 FORMPARTS 函数
- DATEFORMPARTS(year, month, day)
- DATETIME2FORMPARTS(year, month, day,hour,minute,seconds,fractions,precisions)
- DATETIMEFORMPARTS(year, month, day,hour,minute,seconds.millseconds)
- DATETIMEOFFSETFORMPARTS(year,month,day,hour,minute,seconds,fractions,hour_offset,minute_offset,precision)
- SMALLDATETIMEFORMPARTS(year, month, day,hour,minute)
- TIMEFORMPARTS(hour,minute,seconds,fractions,precisions)
这是SQL Server 2012中引入的,它们接受代表日期和时间各个部分的整数值,并根据这些值构建一个所请求类型的值。
2.7.9 EOMONTH 函数
EOMONTH(input[,months_to_add])
这是SQL Server 2012引入的函数。它接受一个日期和时间值输入,并返回相应的每个月的最后一天,作为 DATE 数据类型。第2个可选参数指示要增加多少个月。
2.8.1 目录视图

02.jpg

04.jpg
2.8.2 信息架构视图
信息架构视图是一个视图合集,其位于

27.jpg

10.jpg
2.8.3 系统存储过程和函数

32.jpg

12.jpg

29.jpg

03.jpg

96.jpg

71.jpg

81.jpg
- 在SQL SERVER 中 NULL 默认为无穷小,所以排序时默认排在前面。
联接的3个基本类型是交叉联接、内部联接和外部联接。交叉联接仅处理阶段——笛卡尔乘积,内部联接应用两个阶段——笛卡尔乘积和筛选,外部联接应用三个阶段——笛卡尔乘积、筛选和添加外部行。
3.1.1 ANSI SQL-92 和 89 语法
两种语法没有逻辑或性能上的差异,但推荐使用92的SQL语法。
3.1.2 自交叉联接
可以对一个表的多个实例进行联接,支持联接的基本类型,这功能就是自联接。
3.1.3 生成数字表
自联接生成整数数列(1,2,3....)结果集非常方便。
内部联接是默认联接,所以是可选的。
3.2.1 ANSI SQL-92、89 语法和安全性
语法具有在联接安全性方面比较好,比如忘记写后面的联接条件时,SQL语句会运行异常,以便您对SQL进行修改。然而对于语法来说,如果忘记在后添加条件,此时SQL也可以进行有效查询,返回了错误的结果集,并且由于查询不会失败,SQL可能会运行一段时间。而且,其他维护人员也不会知道些SQL语句是交叉联接还是内联接。所以,建议使用语法的SQL。
3.3.1 复合联接
复合联接就是在之后涉及多个属性的简单联接。
3.3.2 不等联接
联接条件除了号之外还有其他任何运算符的联接即为不等联接

36.jpg
3.3.3 多联接查询
一般来说,当子句中出现多个表运算符时,表运算符会从左到右进行逻辑处理。也就是说,第一个运算符生成的结果集将会被视为第二个运算符的左侧驱动表,以此类推。
与其它联接相比,外部联接更难把握,因为你需要清楚知道哪个表的数据应该保留还是去掉。
3.4.1 外联接基础知识
外联接的语法是 和 , OUTER关键字可选,保留左侧表的行,则相反,则是两侧的行都需要保留。
Customers表中有两位客户(22、75)是没有orderid的,在Orders返回的orderid属性中是。逻辑上,这两个客户会被联接的第二阶段(基于的筛选)过滤掉,但是在第三个阶段将其作为外部行添加回了结果集。而在内联接中,这两行是不会返回的。这两行是在保留左侧表中所有行时添加的。
所以在外联接的的结果中,保留的行有两种:内部行和外部行。内部行是基于与另一侧匹配的行,外部行则是未匹配的行。
外部联接的一个混乱问题是:是在子句还是子句进行筛选。子句并不确定行是否会最终显示在输出的结果集中,只是判断行是否与另一侧是否匹配。所以,当需要表达的谓词不是最终结果时,在子句中进行指定谓词。当需要在外部行生成后再筛选,则应当使用子句。子句是在子句之后进行处理的,即外部行生成后。
3.4.2 其他外联接知识
- 包含缺失值
- 从外联接的非保留侧筛选属性
当需要检查涉及外部联接的代码查找
- 时,要查的项目之一就是WHERE子句,查看是否引用了非保留侧的属性。这是因为联接非保留侧的属性在输出行中是NULL标记,通常NULL的operator value 形式的表达式会生成UNKNOWN值。WHERE子句通常会过滤掉UNKNOWN值,这样的谓词会导致所有外部行被过滤掉,实际上就抵消了外联接 。逻辑上就是实现了一个内联接。
- 在多联接查询中使用外联接
在2.5中“同时操作”的概念不适用于 FROM 阶段中表运算符的处理,表运算符是从左到右进行逻辑计算的,重新排列在外联接中的顺序可能会生成不同的输出结果。
下面这个
- 是上面的
- 的变异,第一个联接返回的是客户及其订单,以及没有订单的客户(即外部行,orderid为NULL标记)。第二个 o.orderid = od.orderid 作为内联接的联接条件,生成的结果将会是左右两侧表都有相应 orderid 记录的结果集。因此,第一个联接(外联接)得到的
- 将不会作为结果输出。所以,外联接后跟一个内联接或是右外联接查询都会使得
- 被删除。当然这是假设联接条件是来自左侧的NULL标记和右侧的任意值进行比较。
解决方法:
- 第二个联接使用LEFT JOIN
- 内联接先进行查询,再使用一个RIGHT JOIN
- 使用
- 将内联接括起来,使得内联接变成一个独立的逻辑阶段
- 外部联接使用COUNT聚合
通常,不应该将外部行作为计数目标。进行COUN计算时不要使用
- 来进行计数,应当使用
- 代替。
- 21.jpg
- 66.jpg
- 48.jpg
- 33.jpg
- 56.jpg
最外面查询的查询结果集返回给调用者,被称为外部查询。内部查询的查询结果被用于外部查询,称为内部查询。
4.1.1 自包含标量子查询示例
如果子查询没有返回值,则返回 NULL 。而与NULL的都会生成 NUKNOWN, 然而查询筛选是不返回筛选表达式试算为 UNKNOWN 的行。
4.1.2 自包含多值子查询示例
多值子查询是作为单个列,返回多个值的子查询,无论子查询是否是自包含的。可使用IN谓词进行多值子查询操作。
没有明确的经验方法表示子查询比联接要好,所以,在写SQL时先以直观的形式对指定任务写一个解决方案查询,如果性能不满意,可以尝试查询调教来进行调优,如:。
在子查询中可以不使用
相关子查询引用的表属性位于外部查询中,这意味着,该子查询依赖于外部查询并且无法单独调用。
4.2.1 EXISTS 谓词
使用 EXISTS 可作为一个子查询作为输入,如果子查询返回任意行,EXISTS 返回TRUE,否则返回FALSE,所以 EXISTS 是一个两值逻辑运算。
EXISTS 相当于短路计算功能,即SQL Server 只要知道子查询返回了一行或者没有数据返回就足够了, 它不需要处理所有符合条件的行。
与其他大多数情况不同,在 EXISTS的上下文子查询中使用星号(*)并无不妥之处,EXISTS只关心匹配行的存在,并不关心SELECT列表中指定的列。数据库会自动忽略查询的 SELECT 列表, 所以并不会带来大的性能损耗。相比于,使用更让人容易理解,更加直观。
4.3.1 返回前一个或下一个值

73.jpg

97.jpg
PS:在SQL2012中引入了 LAG和 LEAD两个新开窗函数,允许按照指定排序从“前一个”或“后一个”返回一个元素。
4.3.2 使用运行聚合
运行聚合是随着时间累积值的聚合。

51.jpg
4.3.3 不当子查询处理
4.3.3.1 NULL故障
T-SQL 使用三值逻辑,下面将演示当子查询涉及NULL标记并且没有考虑三值逻辑情况下演变而来的问题。

这一次查询返回的是一个空集。
我们知道IN返回的是TRUE,NOT IN则为FASLE。 如果Orders表中存在有一条custid为NULL的记录,Customers表的custid与该记录进行比较时产生的是UNKNOWN,所以整个 的返回结果是UNKNOWN。这意味着,这是一种不知道custid是否出现在集合中,也不知道其是否求出现在集合中的情况。总之,当对一个至少返回一个NULL的子查询使用谓词时,外部查询总是返回空集合。
- 列不允许NULL标记,将其定义为NOT NULL是什么必要的。
- 编写所有查询时,应考虑三值逻辑(TRUE,FALSE和UNKNNOW)的所有可能的三种真值。
- 考虑使用EXISTS代替IN
4.3.2 子查询列中的替换错误
到此这篇plsql12注册码(plsqldeveloper12注册码)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/sqlbc/37051.html