我有一张如下表格
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查询中的哪个方法可以解决我的问题?
答案 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的记录。您可以将其转换为查询以包含您提到的范围,但不确定是否真的有必要。
希望这有帮助。