如何搜索最小免费价值

时间:2015-02-04 23:56:22

标签: mysql sql hibernate

我有一张这样的表:

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;

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

这是一个找到所有差距的函数:

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

答案 2 :(得分:0)

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

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 |
+----------+