在测试我对 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
表达方式:
last_value(bal) over (partition by [Session ID] order by id) as lv
返回不同于以下内容的内容:
first_value(bal) over (partition by [Session ID] order by id DESC) as fv_desc
这是结果(注意lv
一组内的变化值):
lv fv_desc
500 500
800 500
900 500
140 140
120 140
100 140
SQL Fiddle 的示例,带有一些额外的列。 反转order by
或省略partition by
似乎不会影响last_value()
返回的内容。
如果我正确阅读了MSDN 页面,它表明last_value()
应该与 的相反first_value()
,这与我在测试期间观察到的不同。
做last_value()
它应该做的事吗?为什么last_value()
允许你指定一个partition
and/ororder by
子句,而它似乎也不使用呢?
发生这种情况是因为默认窗口框架是
range between unbounded preceding and current row
,因此last_value()
除非您更改框架,否则永远不会超出当前行。来自 MSDN:
由于
last_value()
有一个可选order by
子句,它的默认窗口框架在当前行结束。因此,使用默认框架,无论您选择哪个分区或排序,last_value()
都会返回当前行的值。