我找不到在SQL中Partition By
窗口函数提及执行顺序的任何源代码。
它与Group By
的顺序相同吗?
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>
条件,否则结果是错误的?
答案 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'
WHERE
在Partition 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