And*_*mar 6 sql-server window-functions
在测试我对SQL 的回答- 从每个组的第一行和最后一行获取数据时,我注意到一些奇怪的事情。在first_value
和last_value
窗口功能,出现不同的表现。
正如预期的那样,从具有最小值的行中first_value(col1) over (order by col2)
找到 的值。但似乎找到了当前行的值。 似乎与其操作的组或分区无关。col1
col2
last_value(col1) over (order by col2)
last_value
对于下面的查询:
id Session ID bal
0 00000002 100
1 00000002 120
2 00000002 140
3 00000001 900
4 00000001 800
5 00000001 500
Run Code Online (Sandbox Code Playgroud)
表达方式:
last_value(bal) over (partition by [Session ID] order by id) as lv
Run Code Online (Sandbox Code Playgroud)
返回与以下内容不同的内容:
first_value(bal) over (partition by [Session ID] order by id DESC) as fv_desc
Run Code Online (Sandbox Code Playgroud)
结果如下(注意lv
一组内的值变化):
lv fv_desc
500 500
800 500
900 500
140 140
120 140
100 140
Run Code Online (Sandbox Code Playgroud)
带有一些额外列的 SQL Fiddle 示例。 反转order by
或省略partition by
似乎不会影响last_value()
返回的内容。
如果我正确阅读了MSDN 页面,它表明last_value()
应该与 相反first_value()
,这与我在测试期间观察到的不同。
不会last_value()
做它应该做的?为什么当它似乎不使用时last_value()
允许您指定partition
和/或order by
子句?
发生这种情况是因为默认窗口框架是range between unbounded preceding and current row
,因此last_value()
除非您更改框架,否则永远不会超出当前行。
如果未指定 ORDER BY,则整个分区用于窗口框架。这仅适用于不需要 ORDER BY 子句的函数。如果未指定 ROWS/RANGE 但指定了 ORDER BY,则 RANGE UNBOUNDED PRECEDING AND CURRENT ROW 用作窗口框架的默认值。这仅适用于可以接受可选的 ROWS/RANGE 规范的函数。例如,排序函数不能接受 ROWS/RANGE,因此即使 ORDER BY 存在而 ROWS/RANGE 不存在,也不应用此窗口框架。
由于last_value()
有一个可选的order by
子句,它的默认窗口框架在当前行结束。因此,对于默认框架,无论您选择哪个分区或排序,都last_value()
将返回当前行的值。
归档时间: |
|
查看次数: |
3772 次 |
最近记录: |