PostgreSQL中的窗口函数

时间:2018-03-25 14:26:25

标签: sql postgresql window-functions

我有下表:

id username
1   Jack
2   Will
3   Grace
4   Niv

我想写一个3列查询,根据字典顺序显示用户名,用户名和用户名。

含义:

before username  after
       Grace     Jack
Grace  Jack      Niv
Jack   Niv       Will
Nive   Will    

我写了这个查询:

select lag(username,1) over (partition by username order by username ) as before,
    username,
    lead(username,1) over (partition by username order by username ) as after
from users
order by username

但它不起作用。它仅在用户名列中显示数据。我做错了什么?

2 个答案:

答案 0 :(得分:4)

您应该删除PARTITION BY

SELECT
    LAG(username, 1) OVER (ORDER BY username) AS before,
    username,
    LEAD(username, 1) OVER (ORDER BY username) AS after
FROM users
ORDER BY username;

<强> DBFiddle Demo

如果您在users(username)中有重复项,则可以添加DISTINCT

SELECT ...
FROM (SELECT DISTINCT username FROM users) AS sub
ORDER BY ...;

修改

  

但它不起作用。它仅在用户名列中显示数据。我做错了什么?

当您使用分区时,基本上将行划分为共享PARTITION BY表达式的相同值的组。所以你的窗口只包含一个值。这就是为什么你得到NULL(没有先前/下一个值)的原因。

<强> DBFidde Demo2

<强> DBFiddle Demo3 with duplicates per window

答案 1 :(得分:0)

不使用窗口函数的另一种方法

select a.username, 
                  (select min(username) from users b
                    where b.username > a.username) as after,
                   (select max(username) from users c
                   where c.username < a.username) as before
 from users a
order by username;