如果为null,则选择其他聚合值?

时间:2014-08-03 23:53:12

标签: sql aggregate-functions

因此,假设我有以下数据样本:

样本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)吗?

4 个答案:

答案 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