样本数据

CREATE TABLE test
    (id integer, session_ID integer, value integer)
;

INSERT INTO test
    (id, session_ID, value)
VALUES
    (0, 2, 100),
    (1, 2, 120),
    (2, 2, 140),
    (3, 1, 900),
    (4, 1, 800),
    (5, 1, 500)
;

当前查询
select
id,
last_value(value) over (partition by session_ID order by id) as last_value_window,
last_value(value) over (partition by session_ID order by id desc) as last_value_window_desc
from test
ORDER BY id

我遇到了 last_value() 窗口函数的问题:
http://sqlfiddle.com/#!15/bcec0/2

在 fiddle 中,我试图在 last_value() 查询中使用排序方向。

编辑:
问题不是:为什么我没有得到所有时间的最后一个值以及如何使用框架子句( unbounded precedingunbounded following )。我知道 first_value(desc)last_value() 的区别以及 last_value() 没有给你所有时间最后一个值的问题:

默认框架子句在当前行之前是无界的。所以第一个值总是给出子句的第一行。因此,是只有一行(框架子句仅包括这一行)还是一百行(框架子句包括所有一百)都没有关系。结果永远是第一个。在 DESC 顺序中它是相同的:DESC 更改排序顺序,然后第一行是最后一个值,无论您获得多少行。
last_value() 的行为非常相似:如果你有一行,它会给你默认框架子句的最后一个值:这一行。在第二行,frame 子句包含两行,最后一行是第二行。这就是为什么 last_value() 不给你所有行的最后一行,而是只给你当前行之前的最后一行。

但是,如果我将顺序更改为 DESC,我希望我首先得到最后一行,所以我在第一行得到这个,而不是在第二行得到最后但第二行,依此类推。但这不是结果。为什么?

对于当前示例,这些是 first_value()first_value(desc)last_value()last_value(desc) 的结果以及我对 last_value(desc) 的期望:
 id | fv_asc | fv_desc | lv_asc | lv_desc | lv_desc(expecting)
----+--------+---------+--------+---------+--------------------
  0 |    100 |     140 |    100 |     100 |    140
  1 |    100 |     140 |    120 |     120 |    120
  2 |    100 |     140 |    140 |     140 |    100
  3 |    900 |     500 |    900 |     900 |    500
  4 |    900 |     500 |    800 |     800 |    800
  5 |    900 |     500 |    500 |     500 |    900

对我来说,ORDER BY DESC 标志似乎在默认框架子句 last_value() 调用中被忽略了。但它不在 first_value() 调用中。所以我的问题是:为什么 last_value() 结果与 last_value(desc) 相同?

最佳答案

LAST_VALUE() 的问题在于窗口子句的默认规则删除了您真正想要的值。这是一个非常微妙的问题,在所有支持此功能的数据库中都是如此。

This 来自 Oracle 博客:



因此,只需使用 FIRST_VALUE() 。这做你想要的:

with test (id, session_ID, value) as (
      (VALUES (0, 2, 100),
              (1, 2, 120),
              (2, 2, 140),
              (3, 1, 900),
              (4, 1, 800),
              (5, 1, 500)
      )
     )
select id,
       first_value(value) over (partition by session_ID order by id) as first_value_window,
       first_value(value) over (partition by session_ID order by id desc) as first_value_window_desc
from test
order by id

关于sql - 窗口函数 : last_value(ORDER BY . .. ASC) 与 last_value(ORDER BY ... DESC) 相同,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42299101/

10-11 22:10
查看更多