【问题标题】:SQL - Find the lowest unused numberSQL - 查找最小的未使用数字
【发布时间】:2017-02-10 13:17:18
【问题描述】:

我在 2 个不同的表中有一个“数字”列。这不是 ID。

我已经创建了一个这样的联合:

SELECT number FROM table1 UNION SELECT number FROM table ORDER BY number ASC

这会导致以下结果:

number
=====
1
2
3
5
6
8

如何找到最小的未使用号码?在这种情况下,它将是 4。一旦使用了 4,它将是 7,等等

【问题讨论】:

  • 在这个问题的某个地方潜伏着一个条件,正在寻找机会直接比赛并咬你!小心竞争条件。

标签: mysql sql


【解决方案1】:

这是一种方法:

select min(number + 1)
from t
where not exists (select 1 from t t2 where t2.number = t.number + 1);

对于两个不同的表,我将其表述为:

select min(x)
from ((select min(number + 1) as x
       from t1 t
       where not exists (select 1 from t1 tt1 where tt1.number = t.number + 1)
             not exists (select 1 from t2 tt2 where tt2.number = t.number + 1)
      ) union all
      (select min(number + 1) as x
       from t2 t
       where not exists (select 1 from t1 tt1 where tt1.number = t.number + 1)
             not exists (select 1 from t2 tt2 where tt2.number = t.number + 1)
      )
     ) t;

这看起来更复杂,但它可以在每个表中使用(number) 上的索引(如果存在这样的索引)。

【讨论】:

    【解决方案2】:

    假设您的变量number 是一个整数。

    首先我会在一个范围内创建一个数字序列(下面描述的过程是从这个解决方案中提取的:get the first N positive integers

    CREATE TABLE list_of_numbers (number INT NOT NULL PRIMARY KEY AUTO_INCREMENT)
    CREATE PROCEDURE create_sequence_of_numbers(max_number INT)
    BEGIN
            DECLARE _min_number INT;
            SET _min_number = 1;
            WHILE _min_number <= max_number DO
                    INSERT INTO list_of_numbers SELECT  _min_number;
                    SET _min_number = _min_number + 1;
            END WHILE;
    END
    $$
    

    有了这个序列,我们可以创建以下查询:

    select min(number) from list_of_numbers where number not in (SELECT your_number FROM table1 UNION SELECT your_number FROM table)
    

    【讨论】:

      【解决方案3】:

      假设您的号码从 1 开始总是低于查询将给出未使用的号码

      select min(rank) as Num from 
      (select num,@curRank1 := @curRank1 + 1 AS rank from (SELECT num1 as num FROM t1 
      UNION
      SELECT num2 as num FROM t2) a1, (SELECT @curRank1 := 0) r ORDER BY num ASC) tab where num != rank;`
      

      【讨论】:

        猜你喜欢
        • 2010-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-26
        • 1970-01-01
        • 2014-08-03
        相关资源
        最近更新 更多