MySQL:找到最低的免费号码或追加

时间:2018-01-23 12:19:36

标签: mysql sql

我正在寻找一种解决方法,如何找到所有数据行之间的最小列数。

我的表"bot_instances"有一个名为"bot_port"的列。 我有一个定义的最低端口9000,可能有端口开放。

例如,可能有数据行9000,9001,9005,9006,则所需查询应返回9002

也可能是9001,9002,9004,然后查询应该返回9000 或者可能是9000,9001,9002,那么结果应该是9003

我在这里找不到解决方案。我只发现了一个回复所有数字但存在的第二个字段将数字标记为空闲。 对我来说,表格中缺少免费号码。只有使用过的端口的记录。

我希望有人可以帮助我。

提前致谢!

2 个答案:

答案 0 :(得分:4)

我想你只想:

select (case when tt.min_port > 9000 then 9000
             else min(t.port) + 1
        end)
from t cross join
     (select min(port) as min_port from t) tt
where not exists (select 1 from t t2 where t2.port = t.port + 1);

大多数外部查询获取缺少的第一个端口。 min_port的附加联接用于确定是否缺少第一个值。

答案 1 :(得分:0)

您还可以使用变量来获取第一个可用端口:

SELECT MIN(bot_port) - port_diff + 1 AS available_port
FROM (
   SELECT bot_port,
          IF(@t := @p, IF(@p := bot_port, bot_port - @t, 0), 0) AS port_diff
   FROM bot_instances
   CROSS JOIN (SELECT @t :=0, @p := 8999) AS v
   ORDER BY bot_port) AS t
WHERE t.port_diff > 1   

给出以下输入数据集:

bot_port
--------
9000
9001
9002
9006
9007

内部查询返回:

 bot_port, port_diff
---------------------
 9000       1
 9001       1
 9002       1
 9006       4
 9007       1

外部查询得到9006,这是>之后的第一个端口。 1,减去port_diff以获取先前的端口值,然后添加1以获取下一个端口,这是第一个可用端口。

Demo here

给出以下输入数据集:

bot_port
--------
9001
9002
9006
9007

内部查询返回:

bot_port, port_diff
-------------------
9001       2
9002       1
9006       4
9007       1

因此,此边际情况的外部查询返回9001 - 2 + 1 = 9000