【问题标题】:Find gap in SQLite table with index based on two variables使用基于两个变量的索引在 SQLite 表中查找间隙
【发布时间】:2021-12-11 21:33:09
【问题描述】:

我们在移动应用上使用 SQLite 数据库。在其中一张表中,我们有一个基于两个变量的自动递增计数器。我们检测到计数器出现间隙的问题,我们需要找到间隙索引的开始/结束。

所以表格看起来像这样(示例)

X_VAR Z_VAR COUNTER
AA    BB       1
AA    BB       2
AA    BB       3
AA    BB       4
AA    BB       8 <<<< gap 4-8
CC    DD       1
CC    DD       2
CC    DD       3
CC    DD       4
CC    DD       7 <<<< gap 4-7

因此,对于表中出现的 X_VAR 和 Z_VAR 的任何组合,我们需要确定计数器是否包含间隙,如果是,则间隙的开始位置在哪里(以便我们可能用虚拟条目填充它)。有没有一种有效的方法可以使用 sql 来检测这一点,而无需遍历所有条目的数组(表中可能有 30k -100k 条目)?

【问题讨论】:

    标签: sql sqlite


    【解决方案1】:

    可以使用LEAD窗口函数:

    WITH gaps AS (
      SELECT *, LEAD(counter) OVER (PARTITION BY x_var, z_var ORDER BY counter) as next_counter
      FROM mytable
    )
    SELECT *
    FROM gaps
    WHERE counter + 1 <> next_counter
    

    通过递归查询插入缺失的计数器值:

    INSERT INTO mytable (x_var, z_var, counter)
    WITH gaps AS (
      SELECT *, LEAD(counter) OVER (PARTITION BY x_var, z_var ORDER BY counter) as next_counter
      FROM mytable
    ), cte AS (
      SELECT x_var, z_var, counter + 1 AS counter, next_counter - 1 AS end_counter
      FROM gaps
      WHERE counter + 1 <> next_counter
      UNION ALL
      SELECT x_var, z_var, counter + 1, end_counter
      FROM cte
      WHERE counter < end_counter
    )
    SELECT x_var, z_var, counter 
    FROM cte
    

    db<>fiddle

    【讨论】:

    • 这不会在序列的开头找到间隙。 (如果缺少计数器 1)假设所有计数器都需要从 0 开始
    • 更新版本,开头缺少计数器 - db<>fiddle
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多