【问题标题】:How to search the minimum free value如何搜索最小可用值
【发布时间】:2015-02-04 23:56:22
【问题描述】:

我有一张这样的桌子:

create table thing (
  id bigint primary key auto_increment,
  code integer not null,
  description varchar(100)
);

表格通常有连续的代码,但用户可以将生成的代码更改为其他更方便他的代码,这样他就可以打破链。他也可以删除一些thing

所以,我试图弄清楚如何获得第一个未使用的代码

例如:

  • 如果我有 1、2,我想得到 3
  • 如果我有 1、2、3、50 和 51,我想得到 4。

我认为在接下来的两个查询中可以解决我的问题,但它们似乎都不是一个好的选择。

第一个使用exists,我认为它是低效的,因为它具有二次顺序。

select min(code)+1 from thing t
where not exists (select * from thing where code = t.code + 1);

第二个是不可能在 Hibernate HQL 查询上实现的,因为我正在尝试使用一个奇怪的连接子句t1.code = t2.code - 1

select min(t1.code)+ 1 
from thing t1 left join thing t2 on t1.code = t2.code - 1
where t2.id is null;

【问题讨论】:

  • 这是一个很好的相关问题,但它并没有解决我的问题。解决方案包括我不能在 Hibernate 上使用的 Exists 或奇怪的左连接
  • 获得第一个“未使用”代码后,您将如何处理?
  • 我想建议用户使用该值,因此他不必考虑thing 的新代码。

标签: mysql sql hibernate


【解决方案1】:

这个技术怎么样。创建临时表@values

DECLARE @values AS TABLE(value INT);

用从1MAX(code) + 1 的所有整数填充它

DECLARE @limit AS INT;
SET @limit = (SELECT MAX(ISNULL(code, 0)) + 1 FROM thing);
DECLARE @i INT;
SET @i = 1;
WHILE (@i <= @limit)
BEGIN
    INSERT INTO @values VALUES(@i);
    SET @i = @i + 1;
END

那么下面的查询给你解决方案

SELECT TOP 1 v.value
FROM @values AS v
LEFT OUTER JOIN thing AS t ON v.value = t.code
WHERE t.code IS NULL

【讨论】:

    【解决方案2】:

    这是一个查找所有间隙的函数:

    SELECT (t1.id + 1) as gap_starts_at, 
       (SELECT MIN(t3.id) -1 FROM thing t3 WHERE t3.id > t1.id) as     gap_ends_at
    FROM thing t1
    WHERE NOT EXISTS (SELECT t2.id FROM thing t2 WHERE t2.id = t1.id + 1)
    HAVING gap_ends_at IS NOT NULL
    

    gap_starts_at - 当前间隙中的第一个 id
    gap_ends_at - 当前间隙中的最后一个 id

    【讨论】:

    • 您的解决方案与我的第一个解决方案非常相似,但如果可以,我想避免使用EXISTS
    【解决方案3】:

    这是一个想法。这不是一个完整的解决方案,但值得考虑......

    SELECT x.code+1 
      FROM thing x 
      LEFT 
     OUTER
      JOIN thing y 
        ON y.code = x.code+1 
     WHERE y.code IS NULL 
     ORDER 
        BY x.code 
     LIMIT 1;
    +----------+
    | x.code+1 |
    +----------+
    |        4 |
    +----------+
    

    【讨论】:

    • 对,我已经考虑过了(我的第二个选项),但我不能在 Hibernate 中进行那种加入
    • 我不太了解hibernate,但我的理解是它确实支持left outer join
    • 是的,但我无法定义它用于连接的字段,而且我必须在模型中预定义关系。
    猜你喜欢
    • 1970-01-01
    • 2014-11-03
    • 2014-01-12
    • 2019-08-18
    • 2015-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-30
    相关资源
    最近更新 更多