这是Netezza,它有一种Postgres的味道
我正在使用first_value
和last_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
答案 0 :(得分:3)
在用于“运行”计算的窗口函数order by
中,因此对于第一行FIRST_VALUE
和LAST_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;