为什么更改窗口函数“MAX() OVER()”的ORDER BY部分中的列会影响最终结果?

Pan*_*tea 4 sql-server query t-sql window-functions sql-server-2016

我有一个具有以下结构的表,它是数据:

create table test_table
(
Item_index   int,
Item_name    varchar(50)
)

insert into test_table (Item_index,Item_name) values (0,'A')
insert into test_table (Item_index,Item_name) values (1,'B')
insert into test_table (Item_index,Item_name) values (0,'C')
insert into test_table (Item_index,Item_name) values (1,'D')
insert into test_table (Item_index,Item_name) values (0,'E')
Run Code Online (Sandbox Code Playgroud)

我想知道为什么更改order by查询部分中的列会更改结果?在QUERY-1, I useditem_indexQUERY-2I useditem_name列中按部分顺序排列。我认为这两个查询必须生成相同的结果because I used item_index in both queries for partitioning!我现在完全困惑了!为什么按列排序会影响最终结果?

查询-1:

select t.*,
       max(t.Item_name)over(partition by t.item_index order by item_index) new_column
from test_table t;
Run Code Online (Sandbox Code Playgroud)

结果:

Item_index  Item_name     new_column
----------- --------------------------
0           A                E
0           C                E
0           E                E
1           D                D
1           B                D
Run Code Online (Sandbox Code Playgroud)

查询-2:

select t.*,
       max(t.Item_name)over(partition by t.item_index order by item_name) new_column
from test_table t;
Run Code Online (Sandbox Code Playgroud)

结果:

Item_index  Item_name  new_column
----------- -----------------------
0           A             A
0           C             C
0           E             E
1           B             B
1           D             D
Run Code Online (Sandbox Code Playgroud)

谁能解释一下这两个查询究竟是如何执行的,以及为什么每个查询都会产生不同的结果?

提前致谢

ype*_*eᵀᴹ 5

SQL Server 的关于窗口函数的文档中给出了不同结果的解释,该ORDER BY部分:

ORDER BY

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

如果指定了它,而ROWS/RANGE没有指定 a,则默认值 RANGE UNBOUNDED PRECEDING AND CURRENT ROW被可以接受可选ROWS/RANGE 规范(例如minmax)的函数用作窗口框架的默认值。

请注意,MIN()MAX()窗口聚合接受可选ROWSRANGE规范。

当没有这样的规范时,他们计算整个分区的 MIN 和 MAX。如果有,他们会计算指定范围内的 MIN 或 MAX。由于您的两个查询指定了不同的订单/范围,因此它们会产生不同的结果。

如果您想要整个分区的 MAX,则删除ORDER BY范围:

如果未指定,则默认顺序为 ASC ,窗口函数将使用 partition 中的所有行