sql - 查找丢失和无序的记录

标签 sql sql-server tsql

架构:

简化 - 列出 ID 号、它们的版本和状态的表格:

CREATE TABLE archive
    ([id] int, [version] int, [status] varchar(1));

INSERT INTO archive
    ([id], [version], [status])
VALUES
    (1, 1, 'A'),
    (1, 2, 'S'),
    (1, 3, 'T'),
    (1, 4, 'A'),
    (2, 2, 'T'),
    (2, 4, 'T'),
    (3, 1, 'A'),
    (3, 3, 'A');

问题:

有些记录缺少完整的历史记录(版本)。所有 ID 应以版本 1 开头,版本号应连续(与上述架构中的 ID 2 和 3 不同)。

所需的输出

所有 ID 的列表,显示其现有版本以及“跳过”的版本。根据下面的示例,输出应如下所示:
id | ver | check
---+-----+------
  1|   1 |   1
  1|   2 |   2
  1|   3 |   3
  1|   4 |   4
  2| NULL|   1
  2|   2 |   2
  2| NULL|   3
  2|   4 |   4
  3|   1 |   1
  3| NULL|   2
  3|   3 |   3

我目前的努力:

问题类似于this one但在已经回答的问题中没有固定的“Table2”。每条记录的版本数未知。

到目前为止,我想出了以下几点:
SELECT sub.id, sub.ver, sub.seq
FROM (
      SELECT CASE WHEN a.id IS NULL THEN b.id ELSE a.id END as 'id', b.version as 'ver', a.seq as 'seq'
      FROM (select *,
                   row_number() over (partition by id order by version asc) as seq
              from archive) a
      FULL OUTER JOIN archive b ON a.id=b.id AND a.seq=b.version) sub
ORDER BY sub.id, sub.ver, sub.seq

有了以下输出,我几乎就到了那里:

enter image description here

任何帮助,将不胜感激。

最佳答案

这可以使用 recursive cte. 实现

with cte as (
  select 1 as ctr, id, max(version) version from archive group by id
  union all 
  select ctr + 1, id, version from cte
  where ctr < version
)
select t1.id, t2.version, ctr as [check] from cte t1
left join archive t2 on t2.id = t1.id and t1.ctr = t2.version
order by t1.id, t1.ctr;

dbfiddle

关于sql - 查找丢失和无序的记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58944819/

相关文章:

SQL Server Reporting Services 2008 R2 - 文件夹和报表安全性

sql-server - 将仅订阅从 SSRS 2008 移动到 SSRS 2012

sql - 我如何选择日期时间作为 ddMMyy,即两位数的年份?

php - 如何通过单击按钮来更新信息?

日期列上的 SQL 数据透视表?

python - 在cursor.execute()中的sql查询中传递多个参数

javascript - 数据表中的多个子行,来自asp.net core中sql server的数据

sql-server - 性能测试 - 我应该创建多少数据

sql-server - 如何在 t-sql 中使用 'execute' 为变量设置值?

xml - T-SQL 将 XML 字段转换为多列数据集