单表查询
一条单表查询的T-SQL一般包含6个字句,他们的执行顺序如下:
from => where => group by => having => select => order by
ORDER BY子句
为什么使用order by
我们知道SQL SERVER中的表是基于关系模型的,而关系模型又是建立在集合论上面的。一个数据库表代表一个集合(如果有重复记录则是多集),集和是无序的,虽然有时候会发现一张表按Id排序,但不能保证每张表都会这样。所以为了保证结果中的行按一定顺序排序,我们需要使用order by。
注意点
- 使用了ORDER BY子句后查询结果将不符合表的要求,因为这时的结果中的行将具有一定的顺序,ANSI称之为游标,一些语言元素与运算不能处理游标。
- ORDER BY是唯一能够引用SELECT处理阶段创建的别名列的阶段。
- 文章开头已经标明ORDER BY是在SELECT阶段之后执行的,不过ORDER BY是可以指定SELECT没有指定的元素的。但是当SELECT子句中指定了DISTINCT时,ORDER BY 只可以指定SELECT中选中的元素。
TOP选项
功能
TOP选项是T-SQL特有的,用于限制查询返回的行数或百分比。
重点
- TOP选项是可以说是在ORDER BY之后执行的,因为当在查询中指定了ORDER BY子句时,TOP将依赖该子句来定义行的逻辑优先顺序。
- 不能在同一查询中既通过ORDER BY列表来为TOP选项决定各行的逻辑优先顺序,同时还想用另一个ORDER BY对输出中的行进行排序以展示数据。
- TOP在DISTINCT之后执行。
PERCENT关键字
TOP选项中可以使用PERCENT关键字,在这种情况下,SQL Server会按照百分比来计算应该返回的满足条件的行数(向上取整)。
WITH THIS关键字
返回和TOP返回结果的最后一行相同的其他所有行。
OVER子句
功能
OVER子句用于为行定义一个窗口,以便进行固定的运算(指定计算的维度)。
注意点
- 带有空的圆括号的OVER子句会对所有的行进行计算,这里的所有行并不一定是在FROM子句中出现的那些表中的所有行,而是在FROM、WHERE、GROUP BY以及HAVING处理阶段完成后仍然可用的那些行。
- OVER子句中指定的ORDER BY逻辑与数据展示没什么关系,并不会改变查询结果表最终的内容。
- 如果在SELECT处理阶段指定了开窗函数,开窗计算会在DISTINCT子句之前进行处理。
PARTITION BY
如果想对行进行限制或分区,则可以使用PARTITION BY子句。
四种排名函数
OVER子句也支持四种排名函数:ROW_NUMBER、RANK、DENSE_RANK、NTILE。
ROW_NUMBER
ROW_NUMBER函数用于为查询的结果集中的各行分配递增的行号,其逻辑顺序通过OVER子句中的ORDER BY语句进行指定。
RANK&DENSE_RANK
与ROW_NUMBER类似,但他们为具有相同逻辑排序值的所有行生成同样的排名。RANK和DENSE_RANK的区别是:RANK表示之前有多少行具有更低的排序值,DENSE_RANK表示之前有多少个更低的排序值。
NTILE
NTILE函数可以把结果中的行关联到组,并为每一行分配一个所属的组的编号。NTILE函数接受一个表示组的数量的输入参数,并要在OVER子句中指定逻辑顺序。
排名函数也支持在OVER子句中使用PARTITION BY语句。