【问题标题】:MySQL: Find lowest free number or appendMySQL:查找最低的可用编号或追加
【发布时间】:2018-01-23 12:19:35
【问题描述】:

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

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

例如,可能有数据行 9000、9001、9005、9006,那么所需的查询应该返回 9002

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

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

我希望有人可以帮助我。

提前致谢!

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    我想你只是想要:

    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 的附加连接用于确定第一个值是否丢失。

    【讨论】:

    • 谢谢这是一个完美的答案
    【解决方案2】:

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

    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,即gap>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 由外部查询返回此边缘情况。

    【讨论】:

    • 也感谢您提供这个解释得很好的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-22
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-20
    • 1970-01-01
    相关资源
    最近更新 更多