从项目中查找下一行和上一行

时间:2018-10-10 12:50:05

标签: postgresql

在一个Web应用程序中,我有一个项目轮播。

<Prev | Item 1 | Item 2 (active) |  Item 3 | Next>

当用户直接访问应预先选择“项目2”的页面时-我需要上一项和下一项。

因此查询应该类似于“给我在项目2之前,项目2之后的行以及仅这两个行。”

因此,如果用户可以访问该项目,则给定以下带有id和boolean字段的伪数据:

CREATE TABLE items (id integer, can_access boolean);

INSERT INTO items SELECT 1,true;
INSERT INTO items SELECT 2,false;
INSERT INTO items SELECT 3,true;
INSERT INTO items SELECT 5,false;
INSERT INTO items SELECT 6,true;

当id:3是活动ID时-我想找到id:1和id:6。

2 个答案:

答案 0 :(得分:3)

使用窗口功能获取所有页面的相对导航,您的查询将如下所示:

SELECT
    lag("id") over w AS prev,
    id,
    lead("id") over w AS next
FROM items
WHERE can_access = true
WINDOW w as (order by id) 

为您提供这些结果:

prev    active    next
-----------------------
NULL    1         3
1       3         6
3       6         NULL

要仅返回3的导航,可以使用中间CTE:

WITH 
    navi(prev, active, "next") AS
    (
        SELECT
            lag("id") over w AS prev,
            id,
            lead("id") over w AS next
        FROM items
        WHERE can_access = true
        WINDOW w as (order by id) 
    )
SELECT * FROM navi WHERE active = 3

答案 1 :(得分:1)

假设您要使用id定义行的顺序:

(
    select *
    from items
    where can_access and id > 3
    order by id
    limit 1
)
union
(
    select *
    from items
    where can_access and id < 3
    order by id desc
    limit 1
)

替代解决方案可以使用窗口函数或自连接,通常上述简单查询更快。