Sql server 在值列表中查找缺少的整数
目前,我有12行,列名为“Value”。这样的样本只是样本数据,真实数据会更多: 我想要的是选择它们以获得如下结果:Sql server 在值列表中查找缺少的整数,sql-server,sql-server-2008,Sql Server,Sql Server 2008,目前,我有12行,列名为“Value”。这样的样本只是样本数据,真实数据会更多: 我想要的是选择它们以获得如下结果: Result Result_Miss 1-4, 6-12, 14 5, 13 我希望避免使用光标逐行工作。动态、基于集合的方法,使用CTE查找缺少的值,并根据这些缺少的值写出可用的范围 -我似乎无法让SqlFiddle与CTE一起工作,否则我会在这里发布一个- 对记录数进行了修改,使其更具动态性: 如果您的值集中始终有“1”,则此操作有效 动态、基于集合的
Result Result_Miss
1-4, 6-12, 14 5, 13
我希望避免使用光标逐行工作。动态、基于集合的方法,使用CTE查找缺少的值,并根据这些缺少的值写出可用的范围 -我似乎无法让SqlFiddle与CTE一起工作,否则我会在这里发布一个- 对记录数进行了修改,使其更具动态性: 如果您的值集中始终有“1”,则此操作有效
动态、基于集合的方法,使用CTE查找缺少的值,并根据这些缺少的值写出可用的范围 -我似乎无法让SqlFiddle与CTE一起工作,否则我会在这里发布一个- 对记录数进行了修改,使其更具动态性: 如果您的值集中始终有“1”,则此操作有效
请尝试以下脚本: DDL 剧本
DECLARE @MinValue INT
DECLARE @MaxValue INT
DECLARE @Temp TABLE(MissingValues INT)
DECLARE @MissingValues VARCHAR(50)
SELECT @MinValue = MIN(Value),
@MaxValue = MAX(Value)
FROM Numbers
;WITH CTE AS
(
SELECT @MinValue Value
UNION ALL
SELECT Value + 1
FROM CTE
WHERE Value + 1 <= @MaxValue
)
INSERT INTO @Temp
SELECT CTE.Value
FROM CTE
LEFT JOIN Numbers N
ON CTE.Value = N.Value
WHERE N.Value IS NULL
OPTION (MAXRECURSION 1000)
SELECT @MissingValues =
STUFF(( SELECT ',' + CAST(MissingValues AS VARCHAR)
FROM @Temp
FOR XML PATH('')),1,1,'')
INSERT INTO @Temp
SELECT @MinValue - 1
UNION ALL
SELECT @MaxValue + 1
;WITH CTE AS
(
SELECT MissingValues,
ROW_NUMBER() OVER(ORDER BY MissingValues ASC) RN
FROM @Temp
)
,Ranges AS
(
SELECT CAST(T1.MissingValues + 1 AS VARCHAR) + '-' +
CAST(T2.MissingValues - 1 AS VARCHAR) Ranges
FROM CTE AS T1
INNER JOIN CTE AS T2
ON T1.RN = T2.RN - 1
)
SELECT STUFF(( SELECT ',' + R.Ranges
FROM Ranges R
FOR XML PATH('')),1,1,'') Result,
@MissingValues AS Result_Miss
请尝试以下脚本: DDL 剧本
DECLARE @MinValue INT
DECLARE @MaxValue INT
DECLARE @Temp TABLE(MissingValues INT)
DECLARE @MissingValues VARCHAR(50)
SELECT @MinValue = MIN(Value),
@MaxValue = MAX(Value)
FROM Numbers
;WITH CTE AS
(
SELECT @MinValue Value
UNION ALL
SELECT Value + 1
FROM CTE
WHERE Value + 1 <= @MaxValue
)
INSERT INTO @Temp
SELECT CTE.Value
FROM CTE
LEFT JOIN Numbers N
ON CTE.Value = N.Value
WHERE N.Value IS NULL
OPTION (MAXRECURSION 1000)
SELECT @MissingValues =
STUFF(( SELECT ',' + CAST(MissingValues AS VARCHAR)
FROM @Temp
FOR XML PATH('')),1,1,'')
INSERT INTO @Temp
SELECT @MinValue - 1
UNION ALL
SELECT @MaxValue + 1
;WITH CTE AS
(
SELECT MissingValues,
ROW_NUMBER() OVER(ORDER BY MissingValues ASC) RN
FROM @Temp
)
,Ranges AS
(
SELECT CAST(T1.MissingValues + 1 AS VARCHAR) + '-' +
CAST(T2.MissingValues - 1 AS VARCHAR) Ranges
FROM CTE AS T1
INNER JOIN CTE AS T2
ON T1.RN = T2.RN - 1
)
SELECT STUFF(( SELECT ',' + R.Ranges
FROM Ranges R
FOR XML PATH('')),1,1,'') Result,
@MissingValues AS Result_Miss
你绝对需要用SQL完成吗?是的,在我的项目中,有必要得到这样的结果。你绝对需要用SQL完成吗?是的,在我的项目中,有必要得到这样的结果。立即感谢你的回答。但是你能用动态数据处理这种情况吗?我的数据不仅仅是9行。@Langthang在表中添加值1->可能值并减去值之和的概念将为您提供所需的答案。嗨,Adam,值列表如下:插入一个值1、2、3、4、6、7、8、9,10,11,12,14结果将是:-结果:1-4,6-12,14-结果:5,13@langthrang我在回答你最初的问题时只提到了一个小列表,还有一个缺少的值。如果您有一个更复杂的查询,这些问题应该出现在问题中,以便人们知道所有的需求是什么。对于您更新的请求,我将考虑使用递归CTE来构建这一点,但是正如评论中提到的Sur.PAT18,这不是SQL Server通常用来解决的任务。嗨,亚当,您是对的。用C实现起来更容易。无论如何,谢谢你的帮助。谢谢你的回答。但是你能用动态数据处理这种情况吗?我的数据不仅仅是9行。@Langthang在表中添加值1->可能值并减去值之和的概念将为您提供所需的答案。嗨,Adam,值列表如下:插入一个值1、2、3、4、6、7、8、9,10,11,12,14结果将是:-结果:1-4,6-12,14-结果:5,13@langthrang我在回答你最初的问题时只提到了一个小列表,还有一个缺少的值。如果您有一个更复杂的查询,这些问题应该出现在问题中,以便人们知道所有的需求是什么。对于您更新的请求,我将考虑使用递归CTE来构建这一点,但是正如评论中提到的Sur.PAT18,这不是SQL Server通常用来解决的任务。嗨,亚当,您是对的。用C语言实现起来更容易。无论如何,谢谢你的帮助。@Lang thang:请评论或接受答案作为回应。嗨,Nithin,我运行了你的示例。它工作得很好,但我需要编辑一点。非常感谢。@Lang thang:请评论或接受答案。你好,Nithin,我运行了您的样本。它工作得很好,但我需要编辑一点。非常感谢你。
CREATE TABLE Numbers
(
Value INT NOT NULL
);
INSERT INTO Numbers
VALUES (1), (2), (3), (4), (6), (7), (8), (9), (10), (12),(13);
DECLARE @MinValue INT
DECLARE @MaxValue INT
DECLARE @Temp TABLE(MissingValues INT)
DECLARE @MissingValues VARCHAR(50)
SELECT @MinValue = MIN(Value),
@MaxValue = MAX(Value)
FROM Numbers
;WITH CTE AS
(
SELECT @MinValue Value
UNION ALL
SELECT Value + 1
FROM CTE
WHERE Value + 1 <= @MaxValue
)
INSERT INTO @Temp
SELECT CTE.Value
FROM CTE
LEFT JOIN Numbers N
ON CTE.Value = N.Value
WHERE N.Value IS NULL
OPTION (MAXRECURSION 1000)
SELECT @MissingValues =
STUFF(( SELECT ',' + CAST(MissingValues AS VARCHAR)
FROM @Temp
FOR XML PATH('')),1,1,'')
INSERT INTO @Temp
SELECT @MinValue - 1
UNION ALL
SELECT @MaxValue + 1
;WITH CTE AS
(
SELECT MissingValues,
ROW_NUMBER() OVER(ORDER BY MissingValues ASC) RN
FROM @Temp
)
,Ranges AS
(
SELECT CAST(T1.MissingValues + 1 AS VARCHAR) + '-' +
CAST(T2.MissingValues - 1 AS VARCHAR) Ranges
FROM CTE AS T1
INNER JOIN CTE AS T2
ON T1.RN = T2.RN - 1
)
SELECT STUFF(( SELECT ',' + R.Ranges
FROM Ranges R
FOR XML PATH('')),1,1,'') Result,
@MissingValues AS Result_Miss