与其他SQL子句相比,PARTITION BY子句的执行顺序是什么?

时间:2019-01-25 00:48:38

标签: sql sql-server

我找不到在SQL中Partition By窗口函数提及执行顺序的任何源代码。

enter image description here

它与Group By的顺序相同吗?

例如: enter image description here

enter image description here

Select *, row_number() over (Partition by Name) 
from NPtable 
Where Name = 'Peter'

我知道如果首先执行Where,它只会查看Name = 'Peter',然后执行窗口函数,该窗口函数只是聚合此特定人员,而不是整个表聚合,效率更高。

但是当查询为:

Select top 1 *, row_number() over (Partition by Name order by Date) 
from NPtable 
Where Date > '2018-01-02 00:00:00'

是否不需要先对整个表执行window函数,然后应用Date>条件,否则结果是错误的?

3 个答案:

答案 0 :(得分:3)

窗口函数在表的第5阶段与SELECT的同一阶段执行/计算。换句话说,窗口功能将应用于在SELECT阶段“可见”的所有行。

在第二个示例中

Select top 1 *, 
row_number() over (Partition by Name order by Date) 
from NPtable 
Where Date > '2018-01-02 00:00:00'

WHEREPartition by Name函数的row_number()之前被逻辑地应用。

请注意,这是处理查询的逻辑顺序,不一定是引擎如何物理处理数据。

如果查询优化器认为扫描整个表并随后根据WHERE过滤器丢弃日期更便宜,则可以执行此操作。但是,任何一种此类转换都必须以使最终结果与您显示的表中概述的逻辑步骤的顺序一致的方式进行。

答案 1 :(得分:2)

在两个子句中允许

row_number()(和其他窗口函数):

  • SELECT
  • ORDER BY

该函数与该子句的其余部分一起解析。毕竟,它是子句中存在的函数。在这两种情况下,WHERE子句在逻辑上都将首先应用,因此结果将在 过滤之后。

请注意,这是查询的逻辑解析。实际执行可能与查询的结构无关。

答案 2 :(得分:0)

它是查询执行的SELECT阶段的一部分。根据查询,有不同类型的SELECT子句。

  • 选择
  • 选择分组依据
  • 选择排序依据
  • 选择超过
  • 选择进入
  • 选择拥有

PARTITION BY位于SELECT OVER子句中。在此,结果集的窗口是从先前阶段生成的结果集(从FROM,WHERE,GROUP BY等)中生成的。

  

OVER子句定义一个窗口或用户指定的一组行   查询结果集。然后,窗口函数会为每个窗口计算一个值   窗口中的行。您可以将OVER子句与函数一起使用   计算汇总值,例如移动平均值,累计值   总计,运行总计或每个组的前N个结果。

     

OVER ( [ PARTITION BY value_expression ] [ order_by_clause ] )

     

参数

     

PARTITION BY 将查询结果集划分为多个分区。窗户   函数分别应用于每个分区并进行计算   重新启动每个分区。

     

value_expression 指定行集所在的列   分区的。 value_expression只能引用可用的列   通过FROM子句。 value_expression无法引用表达式或   选择列表中的别名。 value_expression可以是一列   表达式,标量子查询,标量函数或用户定义   变量。

     

定义每个行中行的逻辑顺序   结果集的分区。也就是说,它指定逻辑顺序   在其中执行窗口函数的计算。

     

order_by_expression 指定要对其进行排序的列或表达式。   order_by_expression只能引用由   FROM子句。不能指定整数来表示列名   或别名。

您可以详细了解SELECT-OVER