SQL Server找到丢失的号码

时间:2014-08-31 08:42:10

标签: sql sql-server tsql

我有一张如下表格

id  name  year
--------------
1    A     2000
2    B     2000
2    B     2000
2    B     2000
5    C     2000
1    D     2001
3    E     2001

以及你在2000年看到我们错过了id' 3'和id' 4'在2001年,我们错过了id' 2'。我想生成我的第二个表,其中包括错过的项目。

第二桌:

From-id   to-id    name    year
--------------------------------
3          4        null   2000
2          null     null   2001

SQL查询中的哪个方法可以解决我的问题?

3 个答案:

答案 0 :(得分:2)

序列中的间隙和岛屿是此问题的名称。你看了这个article

答案 1 :(得分:1)

这里有一些东西让你入门:

WITH cte AS
(
    SELECT * 
    FROM 
    (VALUES
    (1),(2),(3),(4),(5)
    ) Tally(number)
), cte2 as
(
    SELECT DISTINCT [year]
    FROM
    (VALUES
    (2000),(2000),(2001)
    )tbl([year])
), cte3 as
(
    SELECT * 
    FROM cte
    CROSS JOIN cte2
)
SELECT * 
FROM cte3
LEFT OUTER JOIN YourTable ON cte3.number = YourTable.id AND cte3.[year] = YourTable[year)

注意:请避免使用保留关键字作为列名(例如年份)。 此外,由于我不知道你如何处理多个缺失范围,我没有格式化输出以反映范围。例如:如果只有一行id = 3,那么你的预期输出会是什么?

答案 2 :(得分:1)

我可能会将ROW_NUMBER用于此

此查询为您提供正确的ID(如果我正确解释您的问题):

SELECT 
ROW_NUMBER() OVER (PARTITION BY yr ORDER BY name, yr) as "Correct ID", *
FROM misorder

它分配一个行号(因此每年从1开始的数字增加1)。

为了让你知道哪些缺失,我认为这应该是一个有效的解决方案:

WITH missing AS
(
    SELECT 
    ROW_NUMBER() OVER (PARTITION BY yr ORDER BY name, yr) as "Correct ID", *
    FROM misorder
)
SELECT * FROM missing
WHERE "Correct ID" != "id"

它将第一个查询作为基础,仅选择那些假定的正确ID不等于当前分配的ID的记录。您可以将其转换为查询以包含您提到的范围,但不确定是否真的有必要。

希望这有帮助。