随笔分类 - SQL Server学习随笔
摘要:SQL Server提供了用于获取数据库对象的元数据信息的工具,比如数据库中有什么表、表中有什么列,等等。这些工具包括目录视图(catalog view)、信息架构视图(information schema view)、系统存储过程和函数。这一方面的内容在SQL Server联机丛书的“查询 SQL Server系统目录(Querying the SQL Server System Catalog)“一节有详细的文档。目录视图 目录视图提供了关于数据库中各对象的非常详细的信息,包括SQL Server特定的信息。例如,如果想列出数据库中的各个表,以及它们的架构名称,只要按以下所示的方法去查询
阅读全文
摘要:本节介绍一些对日期和时间数据类型进行操作的函数,包括GETDATE、CURRENT_TIMESTAP、GETUTCDATE、SYSDATETIME、SYSUTCDATETIME、SYSDATETIMEOFFSET、CAST、CONVERT、SWITCHOFFSET、TODATETIMEOFFSET、DATEADD、DATEDIFF、DATEPART、YEAR、MONTH、DAY,以及DATENAME。注意,SYSDATETIME、SYSUTCDATETIME、SYSDATETIMEOFFSET、SWITCHOFFSET,以及TODATETIMEOFFSET是SQL Server 2008中新增
阅读全文
摘要:如果要过滤日期范围(比如,整年或整月),比较自然的方法就是使用YEAR和MONTH之类的函数。例如,以下查询返回2007年中生成的所有订单:[代码] 不过,应该小心的一点是:在大多数情况下,当对过滤条件中的列应用了一定的处理后,就不能以有效的方式来使用索引了。为了潜在地有效利用索引,就需要对谓词进行调整,以便对过滤条件中的列不进行处理,如下所示:[代码] 类似地,不应该使用函数来过滤某个月生成的订单,如下所示:[代码] 而应该使用一个范围过滤条件,如下所示:[代码]
阅读全文
摘要:SQL Server 2008引入了可以单独使用日期和时间部分的数据类型,但在前面的讨论中还没有区分这两部分。如果要在SQL Server 2008之前版本的SQL Server中只使用日期或时间,只能选用同时包含这两种组成部分的DATETIME或SMALLDATETIME数据类型之一。在要实现日期和时间逻辑的地方,也可以使用整数或字符串之类的数据类型,但此处暂不讨论这种用法。如果想选用DATETIME或SMALLDATETIME类型,那么当只使用日期数据时,保存数据的时间值将是午夜(时间部分全是0)。当只使用时间数据时,保存数据的日期值将是基础日期1900年1月1日。 例如,Sales.O
阅读全文
摘要:当需要指定日期和时间数据类型的字符串文字值(常量)时,应该考虑以下几件事。首先,SQL Server并没有提供表达日期和时间字符串的具体方法,这听起来可能会有点古怪;相反,它允许你指定不同类型的字符串文字,再将其转换(显示或隐式地)为相应的日期和时间数据类型。使用字符串来表示日期和时间值是一种最佳实践,如下面这个例子所示:[代码] SQL Server会把文字'20070212'看作是一个字符串常量,而不是日期和时间常量;但因为表达式涉及了两种不同类型的操作数,所以就要把其中一种操作数的类型转换为另一种。当一个表达式涉及的两种操作数具有不同类型时,就需要把其中一种操作数的类型隐式地转换为另一
阅读全文
摘要:在SQL Server 2008之前,SQL Server支持两种表示时间的数据类型:DATETIME和SMALLDATETIME。这两种类型都包括了日期和时间组成部分,而且这两部分是不能分开的。它们在存储需求、支持的日期范围,以及日期的精度上都有所不同。SQL Server 2008新引入了DATE、TIME、DATETIME2和DATETIMEOFFSET数据类型。DATE是单独表示日期的数据类型,TIME是单独表示时间的数据类型,DATETIME2是一种比DATETIME具有更大的日期范围和更好的精度的日期类型,DATETIMEOFFSET具有一个时区组成部分。下表列出了每种日期和时间数
阅读全文
摘要:T-SQL提供了一个LIKE谓词,用于检查字符串是否能够匹配指定的模式。在前面介绍的PATINDEX函数中已经使用了类似的模式。接下来的这节将介绍模式中使用的通配符(wildcard),并演示它们的用法。%(百分号)通配符 百分号代表任意长度的字符串,包括空字符串。例如,以下查询返回姓氏(last name)以字符'D'开头的所有雇员:[代码]_(下划线)通配符 下划线代表任意单个字符。例如,以下查询返回姓氏(last name)第二个字符为'e'的所有雇员:[代码][字符列]通配符 方括号中包含一列字符(例如'[ABC]'),表示必须匹配指定字符中的一个字符。例如,以下查询返回姓氏
阅读全文
摘要:字符串串联运算符(加号[+]) T-SQL提供了加号(+)运算符,可以将两个或多个字符串合并或串联成一个字符串。例如,以下对Employees表的查询将雇员的firstname列、一个空格,以及lastname列串联起来,生成完整的姓名fullname列:[代码] ANSI SQL规定对NULL值执行字符串串联运算也会产生NULL值的结果。这是SQL Server的默认行为。例如,考虑以下对Customers表的查询,如代码如下:[代码] Customers表中一些行的region列是NULL。对于这些行,SQL Server默认在结果的location列中也返回一个NULL: 通过将
阅读全文
摘要:排序规则是字符数据的一个属性,封装了几个方面的特性,包括多语言支持(和Unicode类型有关,因为它支持所有语言)、排序规则、区分大小写、区分重音,等等。要得到系统中目前支持的所有排序规则极其描述,可以查询表函数fn_helpcollations,如下所示:[代码] 例如,排序规则Latin1_General_CI_AS表示:Latin1_General 支持的语言是英语。字典排序 基于字典顺序对字符数据进行排序和比较('A'和'a''B'和'b')。这一排序规则之所以采用字典顺序,是因为当没有显示地定义任何排序规则时,就默认使用字典顺序(更确切地说,排序规则名称中没有显示地出现BIN
阅读全文
摘要:SQL Server支持两种字符数据类型——普通字符和Unicode字符。普通字符数据类型包括CHAR和VARCHAR,Unicode字符数据类型包括NCHAR和NVARCHAR。它们二者的区别是:普通字符使用一个字节(byte)来保存每个字符,而Unicode字符则需要两个字节。当使用普通字符类型时,由于一个列只用一个字节来保存每个字符,所以就限制在这个列中只能使用英语这一语言,因为一个字节只能代表256(2^8)个不同的字符。一个列所支持的语言是由列的有效排序规则(collation)属性决定的。当使用Unicode数据类型时,一个列可以代表65535(2^16)个不同的字符,因为这时用两
阅读全文
摘要:SQL支持一种所谓的同时操作的概念,其含义是认为在同一逻辑查询处理阶段中出现的所有表达式都是同时进行计算的。 例如,这个概念就可以解释为什么不能在SELECT子句中引用为同一SELECT子句中的列分配的别名,即使直觉上看起来应该能够这么做。考虑以下查询:[代码] 以上SELECT列表中第三个表达式对orderyear这一列名的引用是无效的,即使引用表达式位于这个别名的定义“之后”。因为从逻辑上来说,SELECT列表中各表达式的计算是没有顺序的——它们只是一组表达式。在逻辑上SELECT列表中的所有表达式都是在同一时刻进行计算的。因此该查询会生成以下输出:[代码] 再举一个与同时操作有关的
阅读全文
摘要:SQL支持用NULL符号来表示缺少的值,它使用的是三值谓词逻辑,这意味着谓词的计算结果可以是TRUE、FALSE或UNKNOWN(未知)。 T-SQL在这方面遵循了标准。在SQL中处理NULL和UNKNOWN可能非常容易让人困惑,因为人们在直觉上更习惯于用二值逻辑(TRUE、FALSE)来进行思考。更为添乱的是,SQL中不同语言元素处理NULL和UNKNOWN的方式也有所不同。我们先从三值谓词逻辑说起。如果逻辑表达式只涉及已经存在的值,那么最终的计算结果要么为TRUE,要么为FALSE;但是当逻辑表达式涉及缺少的值时,其计算结果就是UNKNOWN。例如,考虑谓词salary 0;当sal
阅读全文
摘要:CASE表达式是一个标量表达式,它基于条件逻辑来返回一个值。注意,CASE是一个表达式,而不是一条语句;也就是会所,不能用它来控制活动的流程,也不能根据条件逻辑来做某些处理。相反,它只是根据条件逻辑来返回某个值。因为CASE是一个标量表达式,所以它可以支持任何标量表达式(如SELECT、WHERE、HAVING,以及ORDER BY子句)、CHECK约束,等等。 CASE表达式有两种格式:简单表达式和搜索表达式。CASE简单格式将一个值(或一个标量表达式)与一组可能的取值进行比较,并返回第一个匹配的结果。如果列表中没有值等于测试值,CASE表达式就返回其ELSE子句(如果存在)中列出的值。如
阅读全文
摘要:T-SQL有几种不同的语言元素可以指定逻辑表达式,例如,查询过滤器(WHERE和HAVING)、CHECK约束,等等。在逻辑表达式中可以使用各种谓词(取值为TRUE、FALSE或UNKNOWN的表达式)和运算符。 T-SQL支持的谓词包括IN、BETWEEN,以及LIKE等。IN这个谓词用于检查一个值(或标量表达式)是否与一组元素中的至少一个相等。例如,以下查询返回订单ID等于10248、或10249、或10250的订单:[代码] BETWEEN这个谓词用于检查一个值是否在指定的范围内,包括两个指定的边界值。例如,以下查询返回订单ID在10300到10310之间的所有订单:[代码] LI
阅读全文
摘要:OVER子句用于为行为定义一个窗口(windows),以便进行特定的运算。可以把行的窗口简单地认为是运算将要操作的一个行的集合。例如,聚合函数和排名函数都是可以支持OVER子句的运算类型。由于OVER子句为这些函数提供了一个行的窗口,所以这些函数也称之为开窗函数。 聚合函数的要点就是要对一组值进行聚合,聚合函数传统上一直以GROUP BY查询作为操作的上下文。在前面的“GROUP BY”子句的讨论中,我们知道在对数据进行分组以后,查询为每个组只返回一行;因此,也就是要限制所有的表达式为每个组只能返回一个值。 聚合开窗函数使用OVER子句提供窗口作为上下文,对窗口中的一组值进行操作,而不是使
阅读全文
摘要:TOP选项是T-SQL特有的,用于限制查询返回的行数或百分比。当在查询中指定了ORDER BY子句时,TOP将依赖该子句来定义行和逻辑优先顺序。例如,如果要从Orders表返回最近的5个订单,则可以在SELECT子句中指定TOP(5),并在ORDER BY子句中指定orderdate DESC,如以下代码:[代码] 从逻辑查询处理的角度来看,TOP选项是作为SELECT阶段的一部分而处理的,紧接着DISTINCT子句处理之后(如果存在DISTINCT)。注意,当在查询中指定了TOP以后,ORDER BY子句就会起到双重作用。首先,作为SELECT处理阶段一部分的TOP选项要依靠ORDER B
阅读全文
摘要:ORDER BY子句用于展示数据时对输出结果中的行进行排序。从逻辑查询处理来看,ORDER BY是最后处理的一个子句。下面的代码按照雇员ID和订单年份对输出结果进行排序:[代码] 理解SQL最重要的一点就是要明白表不保证是有序的,因为表是为了代表一个集合(如果有重复项,则是多集),而集合是无序的。这意味着,如果在查询表时不指定一个ORDER BY子句,那么虽然查询可以返回一个结果表,但SQL Server可以自由地按任意顺序对结果中的行进行排序。为了确保结果中的行按照一定的顺序进行排序,唯一的方法就是显示地指定一个ORDER BY子句。不过,如果指定了ORDER BY子句,查询结果将不符合表
阅读全文
摘要:SELECT子句用于指定需要在查询返回的结果集中包含的属性(列)。SELECT列表中的表达式可以直接基于正在查询的表的各个列,也可以在此基础上做进一步的处理。例如,在前面的代码中的SELECT列表就包含以下表达式:empid、YEAR(orderdate)、COUNT(*)。如果表达式直接引用了某个列(如empid),那么目标列的名称默认与原始列的名称一样。也可以选择为目标列分配自定义的名称,为此要使用AS子句(例如,empid AS employee_id)。当在表达式中进行了一定的处理(例如,YEAR(orderdate)),或者没有基于原始表的列(如调用CURRENT_TIMESTAMP
阅读全文
摘要:HAVING子句用于指定对组进行过滤的谓词或逻辑表达式,这与WHERE阶段对单独的行进行过滤相对应。只有能让HAVING子句中的逻辑表达式为TRUE的组,HAVING阶段才会把这些组返回到下一个逻辑查询处理阶段。逻辑表达式计算结果为FALSE或UNKNOWN的组将被过滤掉。 因为HAVING子句是在对行进行分组后处理的,所以可以在逻辑表达式中引用聚合函数。例如,在下面所示的代码中,HAVING子句使用了逻辑表达式COUNT(*)1,意味着HAVING阶段过滤器只保留包含多行的组(雇员和订单年份)。[代码] 前面提到GROUP BY阶段创建了16个雇员ID和订单年份组,其中有7个组只包含1
阅读全文
摘要:GROUP BY阶段可以将WHERE逻辑查询处理阶段返回的行按“组”进行组合。每个组由在GROUP BY子句中指定的各元素决定。例如,以下代码所示查询的GROUP BY子句就使用了empid和YEAR(orderdate)元素:[代码] 这意味着对于WHERE阶段返回的数据中出现的每个雇员ID和订单年份值的唯一组合,在GROUP BY阶段将会为其生成一个组。表达式YEAR(orderdate)会调用YEAR函数,只返回orderdate列的年份部分。 如果上面的代码没有GROUP BY子句,并且去掉COUNT(*) AS numorders字段,WHERE子句将返回31行数据,其中有16对
阅读全文

浙公网安备 33010602011771号