是否可以使用SQL返回不在特定数据集中但在值范围内的值列表?
例如,我有一个包含以下内容的列....
Registration_no
1
5
6
9
我想退回所有未使用过的'范围内最小值和最大值之间的整数,在本例中为2,3,4,7和8
这是否可以通过SQL语句实现?
非常感谢,
答案 0 :(得分:0)
您不能使用通用SQL将它们作为值列表。但是,你可以把它们作为范围。
select registration_no + 1 as StartMissingRange, registration_no - 1 as EndMissingRange
from (select r.*,
(select min(registration_no)
from registrations r2
where r2.registration_no > r.registration_no
) as next_ro
from registrations r
) t
where next_ro <> registration_no + 1;
这是通用SQL。还有其他解决方案取决于数据库(例如使用lead()
函数)。如果您希望每行上的列表都有单独的数字,那么递归CTE是许多数据库支持的一种方法。
答案 1 :(得分:0)
CREATE TABLE [table]
(number varchar(250))
INSERT INTO [table] VALUES (1),(5),(6),(9)
SELECT * FROM [table]
DEClARE @a varchar(250)
SET @a = (SELECT MIN(number) FROM [table])
WHILE (SELECT MAX(number) FROM [table] ) > @a
BEGIN
IF @a NOT IN ( SELECT number FROM [table] )
PRINT @a
SET @a=@a+1
END
这将为您提供缺少的数字...... 2,3,4,7,8
答案 2 :(得分:0)
测试数据
DECLARE @TABLE TABLE(registration_no INT)
INSERT INTO @TABLE VALUES
(1),(5),(6),(9)
<强>查询强>
;WITH CTE AS
(
SELECT MIN(registration_no) MinVal
,MAX(registration_no) MaxVal
FROM @TABLE
)
,
RequiredVals
AS
(
SELECT DISTINCT [number]
FROM master..spt_values
WHERE number >= (SELECT MinVal FROM CTE)
AND number <= (SELECT MaxVal FROM CTE)
AND NOT EXISTS (SELECT 1
FROM @TABLE
WHERE registration_no = spt_values.number)
)
SELECT number AS MissingValues
FROM RequiredVals
结果集
╔═══════════════╗
║ MissingValues ║
╠═══════════════╣
║ 2 ║
║ 3 ║
║ 4 ║
║ 7 ║
║ 8 ║
╚═══════════════╝
答案 3 :(得分:0)
只需这样做:
DECLARE @MinVal int
DECLARE @MaxVal int
SELECT @MinVal=Min(registration_no),@MaxVal=Max(registration_no) FROM TableName
;WITH nums AS
(SELECT @MinVal AS value
UNION ALL
SELECT value + 1 AS value
FROM nums
WHERE nums.value <@MaxVal)
SELECT *
FROM nums
WHERE value NOT IN (SELECT registration_no FROM TableName)
结果:
VALUE
2
3
4
7
8
请参阅SQL Fiddle中的结果。
答案 4 :(得分:0)
我可以使用常规SQL中的数字表来执行此操作。这个想法是你有一个表,列只列出所有整数。然后您加入该表以查找丢失的数字。基本上是一个穷人的序列。
CREATE TABLE `Numbers` (
`NUM` int(11) NOT NULL,
PRIMARY KEY (`NUM`)
) ;
用整数填充表格。
SELECT NUM
FROM
(SELECT MIN(Registration_no) AS MIN_Range, Max(Registration_no) AS Max_Range
FROM StackOverflow.Registration) r_temp
INNER JOIN
StackOverflow.Numbers n
ON
n.NUM >= r_temp.MIN_Range AND n.NUM <= r_temp.MAX_Range
LEFT OUTER JOIN
StackOverflow.Registration r
ON
r.Registration_no = n.NUM
WHERE r.Registration_no IS NULL
;
* http://www.sqlperformance.com/2013/01/t-sql-queries/generate-a-set-1
答案 5 :(得分:0)
只需更新下面的“范围”(注意:代码最多只能处理sys.columns表的大小)
/* TABLE OF VALUES */
CREATE TABLE [#table](number varchar(250))
INSERT INTO [#table]
SELECT 1 UNION
SELECT 5 UNION
SELECT 6 UNION
SELECT 9
select * from
(
select row=row_number() OVER (ORDER BY name) from sys.columns
)a
where row BETWEEN 1 and 20 /*CHANGE THIS RANGE*/
and row not in
(
SELECT number FROM [#table] /* TABLE OF VALUES */
)
DROP TABLE [#table]