postgresql 带条件的Posgresql LAG

5jvtdoz2  于 2023-02-08  发布在  PostgreSQL
关注(0)|答案(2)|浏览(157)

我的数据如下所示:
| 身份证|用户|资料|日期|
| - ------|- ------|- ------|- ------|
| 1个|1个|1个|二○二三年二月五日|
| 第二章|第二章|1个|二○二三年二月五日|
| 三个|1个|第二章|二〇二三年二月六日|
| 四个|1个|三个|二〇二三年二月七日|
| 五个|第二章|五个|二〇二三年二月七日|
我想得到一个差异的每一行和前一行的数据为这个用户这样:
| 身份证|用户|资料|日期|差异|
| - ------|- ------|- ------|- ------|- ------|
| 1个|1个|1个|二○二三年二月五日||
| 第二章|第二章|1个|二○二三年二月五日||
| 三个|1个|第二章|二〇二三年二月六日|1个|
| 四个|1个|三个|二〇二三年二月七日|1个|
| 五个|第二章|五个|二〇二三年二月七日|四个|
我可以用LAG函数来做这个,但是没有条件要求差异的用户必须是相同的。在postgres中有条件的话我怎么做呢?

goucqfw6

goucqfw61#

我们可以按如下方式使用LAG()

SELECT id, user, data, date,
       data - LAG(data) OVER (PARTITION BY user ORDER BY date) AS diff
FROM yourTable
ORDER BY date, user;
ipakzgxi

ipakzgxi2#

根据评论:window functions允许您对输入进行分区,按照您的需要缩小每个窗口的上下文:

select *, 
       coalesce(data-(lag(data) over w1),0) as data_diff
from   test
window w1 as (partition by user order by date asc) 
order by date, 
        "user";

单独定义窗口也很方便,这样可以保存空间,并且在lag()的情况下为第一行处理null,在coalesce()的情况下为lead()处理最后一行。
Online demo

相关问题