因此,假设我有以下数据样本:
样本1:
id|name
-------
0 |0
0 |1
0 |2
0 |3
-------
样本2:
id|name
-------
0 |0
1 |1
3 |3
4 |4
-------
样本3:
id|name
-------
0 |0
1 |1
2 |2
3 |3
-------
我想要的是能够返回序列中最小的缺失值,如果可能的话。如果没有,我想将MAX(id)+1
作为可用值返回。
要获得最小的缺失值,我会执行以下操作:
SELECT temptable.id+1 FROM (
SELECT id, LEAD(id, 1) OVER (ORDER BY id) AS lead FROM mytable) AS temptable
WHERE (lead - id) > 1;
对于样本1,这将返回NULL
,对于样本2,将返回NULL
。
现在可以先检查temptable.id
是否为NULL
,如果是,请在单个查询中返回MAX(mytable.id)
吗?
答案 0 :(得分:1)
是。在子查询中计算最大值,然后使用coalesce()
:
SELECT coalesce(id+1, maxid + 1)
FROM (SELECT id, LEAD(id, 1) OVER (ORDER BY id) AS lead,
MAX(id) OVER () as maxid
FROM mytable
) t
WHERE (lead - id) > 1;
顺便说一句,您可以使用not exists
:
select min(id) + 1
from mytable t1
where not exists (select 1 from mytable t2 where t2.id = t1.id + 1);
我认为这同时进行了两次计算。如果id
s全部按顺序排列,那么只有最大的id
会通过where
条件。
答案 1 :(得分:1)
我认为最简单的方法是在所有记录之后添加一个非常大的ID。那么你的查询永远不会返回null值。
首先插入一行:
Insert into mytable values(2147483648,0);
第二种方式使用union all:
SELECT temptable.id+1 FROM (
SELECT id, LEAD(id, 1) OVER (ORDER BY id) AS lead FROM
(select * from mytable union all select 2147483648,0) ) AS temptable
WHERE (lead - id) > 1;
答案 2 :(得分:0)
我猜你要找的是COALESCE
:
COALESCE(value1,value2,value3...)
将返回第一个非空值。
另一种选择是使用CASE WHEN ... THEN ... ELSE ... END
,例如:
CASE WHEN value IS NOT NULL THEN value ELSE other_value END
答案 3 :(得分:0)
根据OP:
使用此样本数据create table #t(
sample int not null
,id int not null
,name int not null
)
insert #t(sample,id,name)
values (1,0,0),(1,0,1),(1,0,2),(1,0,3)
,(2,0,0),(2,1,1),(2,3,3),(2,4,4)
,(3,0,0),(3,1,1),(3,2,2),(3,3,3);
这个SQL病毒按照每个样本的要求执行:
declare @sample int = 1;
SELECT top 1 temptable.id+1 FROM (
SELECT id, LEAD(id, 1) OVER (ORDER BY id) AS lead
FROM (
select id
from #t
where sample = @sample
union all
select 2147483647 -- = 2^31-1 = MAXINT for integer datatype
) t
) AS temptable
WHERE (lead - id) > 1
每次运行都会产生:
Sample id
----------- -----------
1 1
Sample id
----------- -----------
2 2
Sample id
----------- -----------
3 4