在 SQLite table 中查找缺失的记录和缺失的序列 - 其中序列中的第一个条目必须是 1
Finding missing records and missing sequences in SQLite table - where the first entry in the sequence must be 1
原问题及解决方法参考
以下代码正确识别缺失序列,但是,其起点是基于 table 中数据的序列中的最低编号。因此,例如,如果序列应该从 1 开始,但数据中的第一个序列以 5 开头,则结果中不包含 1..4。
关于如何使用预定义的启动序列进行测试的任何提示?
SELECT dir, start, stop
FROM (
SELECT m.id + 1 start,
(SELECT MIN(id) - 1 FROM sequence x WHERE x.__dirpath = m.__dirpath AND x.id > m.id) stop,
m.__dirpath dir
FROM sequence m LEFT JOIN sequence r
ON m.__dirpath = r.__dirpath AND m.id = r.id - 1
WHERE r.id IS NULL
)
WHERE stop IS NOT NULL
ORDER BY dir, start, stop;
您所要做的就是在数据集中为每个 __dirpath
包含 1 行,其中 id
等于 0
,前提是 id
中不存在这样的行 table,因为最小可能 id
是 1
.
您可以在 CTE
.
中使用 UNION ALL
来做到这一点
然后在您的查询中使用 CTE
:
WITH cte AS (
SELECT __dirpath, id FROM sequence
UNION ALL
SELECT DISTINCT __dirpath, '0' FROM sequence
)
SELECT dir, start, stop
FROM (
SELECT m.id + 1 start,
(SELECT MIN(id) - 1 FROM cte x WHERE x.__dirpath = m.__dirpath AND x.id > m.id) stop,
m.__dirpath dir
FROM cte m LEFT JOIN cte r
ON m.__dirpath = r.__dirpath AND m.id = r.id - 1
WHERE r.id IS NULL
)
WHERE stop IS NOT NULL
ORDER BY dir, start, stop;
参见demo。
原问题及解决方法参考
以下代码正确识别缺失序列,但是,其起点是基于 table 中数据的序列中的最低编号。因此,例如,如果序列应该从 1 开始,但数据中的第一个序列以 5 开头,则结果中不包含 1..4。
关于如何使用预定义的启动序列进行测试的任何提示?
SELECT dir, start, stop
FROM (
SELECT m.id + 1 start,
(SELECT MIN(id) - 1 FROM sequence x WHERE x.__dirpath = m.__dirpath AND x.id > m.id) stop,
m.__dirpath dir
FROM sequence m LEFT JOIN sequence r
ON m.__dirpath = r.__dirpath AND m.id = r.id - 1
WHERE r.id IS NULL
)
WHERE stop IS NOT NULL
ORDER BY dir, start, stop;
您所要做的就是在数据集中为每个 __dirpath
包含 1 行,其中 id
等于 0
,前提是 id
中不存在这样的行 table,因为最小可能 id
是 1
.
您可以在 CTE
.
中使用 UNION ALL
来做到这一点
然后在您的查询中使用 CTE
:
WITH cte AS (
SELECT __dirpath, id FROM sequence
UNION ALL
SELECT DISTINCT __dirpath, '0' FROM sequence
)
SELECT dir, start, stop
FROM (
SELECT m.id + 1 start,
(SELECT MIN(id) - 1 FROM cte x WHERE x.__dirpath = m.__dirpath AND x.id > m.id) stop,
m.__dirpath dir
FROM cte m LEFT JOIN cte r
ON m.__dirpath = r.__dirpath AND m.id = r.id - 1
WHERE r.id IS NULL
)
WHERE stop IS NOT NULL
ORDER BY dir, start, stop;
参见demo。