按ID选择行,它是按某个值排序的最接近的行。 PostgreSQL的

时间:2019-04-02 13:31:51

标签: postgresql

我有这样的章节表:

id | title    | sort_number | book_id
1  | 'Chap 1' | 3           | 1
5  | 'Chap 2' | 6           | 1
8  | 'About ' | 1           | 1
9  | 'Chap 3' | 9           | 1
10 | 'Attack' | 1           | 2

Id是唯一的,sort_number对于同一本书(book_id)是唯一的

1)如果我只有当前章节ID,如何按sort_number排序的3个章节(当前,下一个和上一个)的所有数据(3行)如何加载?

2)我如何加载当前章节数据(1行),并且只有下一个ID或上一个ID(如果存在)?

1 个答案:

答案 0 :(得分:1)

可以使用window functions

select id, title, sort_number, book_id, 
       lag(id) over w as prev_chapter,
       lead(id) over w as next_chapter
from chapters
window w as (partition by book_id order by sort_number);

您的示例数据返回:

id | title  | sort_number | book_id | prev_chapter | next_chapter
---+--------+-------------+---------+--------------+-------------
 8 | About  |           1 |       1 |              |            1
 1 | Chap 1 |           3 |       1 |            8 |            5
 5 | Chap 2 |           6 |       1 |            1 |            9
 9 | Chap 3 |           9 |       1 |            5 |             
10 | Attack |           1 |       2 |              |             

上面的查询现在可以用来回答您的两个问题:

1)

select id, title, sort_number, book_id
from (
  select id, title, sort_number, book_id, 
         --first_value(id) over w as first_chapter,
         lag(id) over w as prev_chapter_id,
         lead(id) over w as next_chapter_id
  from chapters
  window w as (partition by book_id order by sort_number)
) t
where 1 in (id, prev_chapter_id, next_chapter_id)

2)

select *
from (
  select id, title, sort_number, book_id, 
         lag(id) over w as prev_chapter_id,
         lead(id) over w as next_chapter_id
  from chapters
  window w as (partition by book_id order by sort_number)
) t
where id = 1