我有一张这样的表:
create table thing (
id bigint primary key auto_increment,
code integer not null,
description varchar(100)
);
该表通常具有连续代码,但用户可以更改其他更方便的生成代码,因此他可以打破链。他也可以删除一些thing
。
所以,我试图找出如何获得第一个未使用的代码。
例如:
我在接下来的两个查询中已经考虑过解决我的问题,但它们似乎都不是一个好选择。
第一个使用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;
答案 0 :(得分:1)
这种技术怎么样?创建临时表@values
DECLARE @values AS TABLE(value INT);
使用1
到MAX(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 |
+----------+