找到第一个不存在的可用值
Find first available value that doesn't exist
我想为 pk 为 book_id
和 chapter_internal_number
的书籍章节创建 table。我不确定如何找到新章节插入的下一个免费 chapter_internal_number
值(章节可以删除,它的 chapter_internal_number
值应该被重新使用)。
如何首先找到书的 chapter_internal_number 可用价值?可用值是 ASC 顺序中不存在的下一个值。
Table book_chapter:
| pk | pk |
| book_id | chapter_internal_number |
| 1 | 1 |
| 1 | 2 |
| 1 | 5 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
预计:
- 对于 book_id=1 是 3
- 对于 book_id=2 是 4
基本上,您想要每本书的章节编号中的第一个空白。我认为您不需要 generate_series()
;您可以使用 lead()
:
将当前章节与下一章节进行比较
select book_id, min(chapter_internal_number) + 1
from (
select bc.*,
lead(chapter_internal_number) over(partition by book_id order by chapter_internal_number) lead_chapter_internal_number
from book_chapter bc
) bc
where lead_chapter_internal_number is distinct from chapter_internal_number + 1
group by book_id
这似乎是表达查询的最自然方式,我怀疑用 generate_series()
枚举所有可能的值应该更有效(我很想知道这两种解决方案的比较表现针对大型数据集)。
我们也可以在外部查询中使用 distinct on
而不是聚合:
select distinct on (book_id) book_id, chapter_internal_number + 1
from (
select bc.*,
lead(chapter_internal_number) over(partition by book_id order by chapter_internal_number) lead_chapter_internal_number
from book_chapter bc
) bc
where lead_chapter_internal_number is distinct from chapter_internal_number + 1
order by book_id, chapter_internal_number
我想为 pk 为 book_id
和 chapter_internal_number
的书籍章节创建 table。我不确定如何找到新章节插入的下一个免费 chapter_internal_number
值(章节可以删除,它的 chapter_internal_number
值应该被重新使用)。
如何首先找到书的 chapter_internal_number 可用价值?可用值是 ASC 顺序中不存在的下一个值。
Table book_chapter:
| pk | pk |
| book_id | chapter_internal_number |
| 1 | 1 |
| 1 | 2 |
| 1 | 5 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
预计:
- 对于 book_id=1 是 3
- 对于 book_id=2 是 4
基本上,您想要每本书的章节编号中的第一个空白。我认为您不需要 generate_series()
;您可以使用 lead()
:
select book_id, min(chapter_internal_number) + 1
from (
select bc.*,
lead(chapter_internal_number) over(partition by book_id order by chapter_internal_number) lead_chapter_internal_number
from book_chapter bc
) bc
where lead_chapter_internal_number is distinct from chapter_internal_number + 1
group by book_id
这似乎是表达查询的最自然方式,我怀疑用 generate_series()
枚举所有可能的值应该更有效(我很想知道这两种解决方案的比较表现针对大型数据集)。
我们也可以在外部查询中使用 distinct on
而不是聚合:
select distinct on (book_id) book_id, chapter_internal_number + 1
from (
select bc.*,
lead(chapter_internal_number) over(partition by book_id order by chapter_internal_number) lead_chapter_internal_number
from book_chapter bc
) bc
where lead_chapter_internal_number is distinct from chapter_internal_number + 1
order by book_id, chapter_internal_number