SQL first_value和last_value

时间:2016-02-08 18:21:19

标签: sql netezza window-functions

这是Netezza,它有一种Postgres的味道

我正在使用first_valuelast_value窗口函数,这些函数给出了不同的值并使我感到困惑。

这是我正在运行的代码:

select
    a.emp_id
    , a.sequence
    , FIRST_VALUE(a.DEP_ID) OVER(PARTITION BY a.emp_id ORDER BY a.sequence) AS first_dept
    , LAST_VALUE(a.DEP_ID) OVER(PARTITION BY a.emp_id ORDER BY a.sequence) AS last_dept
    , FIRST_VALUE(a.sequence) OVER(PARTITION BY a.emp_id ORDER BY a.sequence) AS first_seq
    , LAST_VALUE(a.sequence) OVER(PARTITION BY a.emp_id ORDER BY a.sequence) AS last_seq
FROM
    tname a
WHERE
    1=1
    AND a.event_id IN (1, 2)
    AND a.emp_id=11111

对于emp_id = 1111,这将返回2条记录。

emp_id   SEQuence   FIRST_DEPT  LAST_DEPT   FIRST_SEQ   LAST_SEQ
90565520    1       200800      200800      1           1
90565520    10      200800      200932      1           10

我很困惑为什么last_seq返回1而非10

2 个答案:

答案 0 :(得分:3)

在用于“运行”计算的窗口函数order by中,因此对于第一行FIRST_VALUELAST_VALUE仅返回第一行和第二行的值,它返回两行的值等等。

您可以通过添加sum(a.sequence) over (PARTITION BY a.emp_id ORDER BY a.sequence)之类的内容来确保其中。在您的示例中,它将是1和11(= 1 + 10)。

因此,您应该从order by移除over,并在整个查询结束时添加order by a.DEP_ID, a.sequence

答案 1 :(得分:1)

示例数据:

create table sample (id int, val int);
insert into sample select i, i from generate_series(1,5) i;

在窗口函数中使用order by时,它会计算累积值:

select 
    id, val,
    first_value(val) over (order by val),
    last_value(val) over (order by val),
    sum(val) over (order by val)
from sample;

 id | val | first_value | last_value | sum 
----+-----+-------------+------------+-----
  1 |   1 |           1 |          1 |   1
  2 |   2 |           1 |          2 |   3
  3 |   3 |           1 |          3 |   6
  4 |   4 |           1 |          4 |  10
  5 |   5 |           1 |          5 |  15
(5 rows)

请勿使用order by

select 
    id, val,
    first_value(val) over (),
    last_value(val) over (),
    sum(val) over ()
from sample;

 id | val | first_value | last_value | sum 
----+-----+-------------+------------+-----
  1 |   1 |           1 |          5 |  15
  2 |   2 |           1 |          5 |  15
  3 |   3 |           1 |          5 |  15
  4 |   4 |           1 |          5 |  15
  5 |   5 |           1 |          5 |  15
(5 rows)    

要获得恰好一行,您可以使用DISTINCT ON。添加ORDER BY sequence desc,以便最后一个序列显示在行中:

SELECT DISTINCT ON (a.emp_id)
    a.emp_id
    , a.sequence
    , FIRST_VALUE(a.DEP_ID) OVER(PARTITION BY a.emp_id) AS first_dept
    , LAST_VALUE(a.DEP_ID) OVER(PARTITION BY a.emp_id) AS last_dept
    , FIRST_VALUE(a.sequence) OVER(PARTITION BY a.emp_id) AS first_seq
    , LAST_VALUE(a.sequence) OVER(PARTITION BY a.emp_id) AS last_seq
FROM
    tname a
WHERE
    1=1
    AND a.event_id IN (1, 2)
    AND a.emp_id=11111
ORDER BY
    a.sequence desc;