SQL返回特定范围内未使用的整数值

时间:2014-03-29 16:54:17

标签: sql select

是否可以使用SQL返回不在特定数据集中但在值范围内的值列表?

例如,我有一个包含以下内容的列....

Registration_no
1
5
6
9

我想退回所有未使用过的'范围内最小值和最大值之间的整数,在本例中为2,3,4,7和8

这是否可以通过SQL语句实现?

非常感谢,

6 个答案:

答案 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]