在表格中查找连续的免费数字

时间:2016-04-06 13:26:01

标签: sql sql-server gaps-and-islands

我有一张表,其中包含数字(电话号码)和代码(免费或不可用)。

现在,我需要找到30个连续数字的系列,如079xxx100 - 079xxx130,并且所有这些数字都具有免费状态。

以下是我的表格的示例:

CREATE TABLE numere
(
    value int,
    code varchar(10)
);


INSERT INTO numere (value,code)
Values
 (123100, 'free'),
 (123101, 'free'),
...
 (123107, 'booked'),
 (123108, 'free'),
 (...
 (123130, 'free'),
 (123131, 'free'),
 ...

 (123200, 'free'),
 (123201, 'free'),
...
 (123230, 'free'),
 (123231, 'free'),
 ...

我需要一个SQL查询,让我在这个例子中,123200-123230范围(以及所有下一个可用范围)。

现在,我找到了一个例子,或多或少地做了我需要的事情:

select value, code
from numere
where value >= (select a.value
                from numere a
                left join numere b on a.value < b.value 
                                   and b.value < a.value + 30 
                                   and b.code = 'free'
                where a.code = 'free'
                group by a.value
                having count(b.value) + 1 = 30)
limit 30

但这仅返回前30个可用数字,而不是在我的范围内(0-30)。 (需要13分钟才能执行,呵呵......)

如果有人有想法,请告诉我(我使用的是SQL Server)

4 个答案:

答案 0 :(得分:2)

这似乎适用于我的数据集。修改选择并查看它是否与您的表名一起使用。

DECLARE @numere TABLE
(
value int,
code varchar(10)
);


INSERT INTO @numere (value,code) SELECT 123100, 'free'

WHILE (SELECT COUNT(*) FROM @numere)<=30
BEGIN
    INSERT INTO @numere (value,code) SELECT MAX(value)+1, 'free' FROM @numere
END

UPDATE @numere
SET code='booked'
WHERE value=123105

select *
from @numere n1
inner join @numere n2 ON n1.value=n2.value-30
    AND n1.code='free'
    AND n2.code='free'
LEFT JOIN @numere n3 ON n3.value>=n1.value
    AND n3.value<=n2.value
    AND n3.code<>'free'
WHERE n3.value IS NULL

答案 1 :(得分:1)

这是常见的Island and Gap问题。

VarChar

答案 2 :(得分:1)

您可以使用以下使用SQL LEAD() analytical function的SQL查询

查询表数据以查找预订号码之间的差距
;with cte as (
 select
  value, lead(value) over (order by value) nextValue
 from numere
 where code = 'booked'
), cte2 as (
select
 value gapstart, nextValue gapend,
 (nextValue - value - 1) [number count in gap] from cte
where value < nextValue - 1 
)
select * 
from cte2
where [number count in gap] >= 30

您可以查看SQL教程Find Missing Numbers and Gaps in a Sequence using SQL

我希望它有所帮助,

答案 3 :(得分:1)

目前无法对其进行测试,但这可能会有效:

SELECT a.Value FROM (SELECT Value FROM numere WHERE Code='free' ) a INNER Join (SELECT Value FROM numere WHERE code='free' ) b ON b.Value BETWEEN a.Value+1 AND a.Value+29 GROUP BY a.Value HAVING COUNT(b.Value) >= 29 ORDER BY a.Value ASC

输出应该是所有包含29个免费号码的号码(因此它连续30个号码)