Window PostgreSQL 中的函数
Window functions in PostgreSQL
我有以下 table:
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
但是没用。它仅在用户名列中显示数据。我做错了什么?
您应该删除 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;
如果 users(username)
中有重复项,您可以添加 DISTINCT
:
SELECT ...
FROM (SELECT DISTINCT username FROM users) AS sub
ORDER BY ...;
编辑:
But it doesnt work. It shows me data only in the username column. What am I doing wrong?
当您使用分区依据时,您基本上将行分成组,这些组共享 PARTITION BY
表达式的相同值。所以你的 window 只包含一个值。这就是你得到 NULL 的原因(没有 prior/next 值)。
不使用 window 函数的另一种方法
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;
我有以下 table:
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
但是没用。它仅在用户名列中显示数据。我做错了什么?
您应该删除 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;
如果 users(username)
中有重复项,您可以添加 DISTINCT
:
SELECT ...
FROM (SELECT DISTINCT username FROM users) AS sub
ORDER BY ...;
编辑:
But it doesnt work. It shows me data only in the username column. What am I doing wrong?
当您使用分区依据时,您基本上将行分成组,这些组共享 PARTITION BY
表达式的相同值。所以你的 window 只包含一个值。这就是你得到 NULL 的原因(没有 prior/next 值)。
不使用 window 函数的另一种方法
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;