2.1 Select语句的元素
2.1.2 WHERE 子句
1. 在WHERE子句中,可以指定一个谓词或逻辑表达式,从而过滤由FROM阶段返回的行,只有能让逻辑表达式结果为True的行,才能由WHERE阶段返回给后续的逻辑查询处理阶段。
2.WHERE子句对查询性能有重要影响。在过滤表达式的基础上,SQL Server会计算使用什么索引来访问请求的数据。与打描整个表相比,通过使用索引,有时可以大幅减少
SQL Server在获取请求的数据时付出的代价。
2.1.3 GROUP BY子句
1. GROUP BY阶段可以将前面逻辑查询处理阶段返回的行按组进行组合。每个组由在GROUP BY子句中指定的各元素决定。如果查询涉及到分组,那么GROUP BY阶段之后的所有阶段的操作对象将是组,而不是单独的行。
2.所有的聚合函数都会忽略NULL值,只有一个例外:COUNT(*)
2.1.4 HAVING子句
只有能让HAVING子句中的逻辑表达式为TRUE的组,HAVING阶段才会把这些组返回到下一个逻辑查询处理阶段。
2.1.5 SELECT子句
不管分配别名的表达式是在试图引用它的表达式的左边还是右边,在SELECT子句内部也仍然不能够引用同一SELECT子句中创建的别名列。例如,以下查询是无效的。
SELECT orderid, YEAR(orderdate) AS orderyear, orderyear + 1 AS nextyear FROM Sales.Orders;
2.1.6 ORDER BY子句
1.用于展示数据时对输出结果中的行进行排序。理解SQL最重要的一点就是要明白表不保证是有序的,因为表是为了代表一个集合,而集合是无序的。这意味着,如果在查询时不指定一个ORDER BY子句,那么虽然查询可以返回一个结果表,但SQL Server可以自由地按任意顺序对结果中的行进行排序。
2.ORDER BY是唯一能够引用SELECT处理阶段创建的别名列的阶段,因为它是唯一一个在SELECT阶段之后被处理的阶段。
3.TSQL支持在ORDER BY子句中指定没有在SELECT子句中出现过的元素。但是指定了DISTINCT以后,ORDER BY子句就被限制为只能选取在SELECT列表中出现的那些元素。这一限制背后的原因是:当指定DISTINCT时,一个结果行可能代表多个原始行,因此,可能无法清楚地知道应该使用ORDER BY列表值中多个可能值中的哪一个。
SELECT empid, firstname, lastname, country FROM HR.Employees ORDER BY hiredate;
2.1.7 TOP选项
1.TOP选项是T-SQL特有的,用于限制查询返回的行数或百分比。当使用TOP时,同一ORDER BY子句既担当了为TOP决定行的逻辑优先顺序的角色,同时也担当了它的常规角色(展示数据)。
2.WITH TIES选项:请求返回与TOP N行中最后一行的排序值相同的其他所有行。如下图所示
2.1.8 OVER子句
1.OVER子句用于为行定义一个窗口,以便进行特定的运算。可以把行的窗口简单地理解为运算将要操作的行的集合。聚合开窗函数使用OVER子句提供窗口作为上下文,对窗口中的一组值进行操作,而不是使用GROUP BY子句提供的上下文,这样就不必对数据进行分组,还能够在同一行中同时返回基础行的列和聚合列。
2.如果想对行进行限制或分区,则可以使用PARTITION BY子句
3.OVER子句支持四种排名函数:ROW_NUMBER(行号)、RANK(排名)、DENSE_RANK(密集排名)以及NTILE。
ROW_NUMBER函数用于为查询的结果集中的各行分配递增的序列号,即使行的排序值相同,ROW_NUMBER函数也一定会为其生成唯一的行号值。
RANK表示之前有多少行具有更低的排序值。
DENSE_RANK表示之前有多少个更低的排序值。
NTILE函数可以把结果中的行关联到组,并为每一行分配一个所属组的编号。
2.2 CASE表达式
1.简单表达式:将一个值(或一个标量表达式)与一组可能的取值进行比较,并返回第一个匹配的结果。
2.搜索表达式
2.3 NULL值
1.SQL支持用NULL符号来表示缺少的值,它使用的是三值谓词逻辑,这意味着谓词的计算结果是TRUE、FALSE或UNKNOWN。
2.在不同的语言元素中,SQL对UnKnown的处理也有所不同,SQL对查询过滤条件的处理的正确定义是:"接受True",这意味着要过滤掉False和UnKnown.反之,SQL对Check约束处理的正确定义是:"拒绝False",这意味着要接受True和UnKnown.
3.当进行分组或排序时,认为两个NULL值是相等的。
2.4 同时操作
SQL支持一种所谓的同时操作的概念,其含义是认为在同一逻辑查询处理阶段中出现的所有表达式都是同时进行计算的。
例如,这个概念就可以解释为什么不能在Select子句中引用为同一Select子句中的列分配的别名。