找到第一个不存在的可用值

Find first available value that doesn't exist

我想为 pk 为 book_idchapter_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              |

预计:

基本上,您想要每本书的章节编号中的第一个空白。我认为您不需要 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