我有一个表,必须根据以下条件从中选择一些行。
我试图通过DocumentRef将其分组,并使用具有但只能具有聚合函数的过滤器。我认为在用OR分隔时必须提供多个条件。请给我一些指导。
答案 0 :(得分:1)
将表加入到一个查询中,该查询为所有documentref
(如果不是documentid
或blocknumber
的所有null
返回最大null
都是null
:
select t.*
from tablename t inner join (
select
documentref,
max(case when blocknumber is not null then documentid end) maxid
from tablename
group by documentref
) d on d.documentref = t.documentref
and t.documentid = coalesce(d.maxid, t.documentid)
请参见demo。
结果:
> DOCUMENTID | DOCUMENTREF | WARDID | BLOCKNUMBER
> ---------: | ----------: | -----: | ----------:
> 203962537 | 100000126 | B | A
> 203962538 | 100000130 | B | A
> 203962542 | 100000151 | null | null
> 203962543 | 100000151 | null | null
> 203962544 | 100000180 | B | A
> 203962546 | 100000181 | B | A
> 203962551 | 100000185 | null | null
> 203962552 | 100000186 | B | A
答案 1 :(得分:1)
使用窗口功能:
select t.*
from (select t.*,
sum(case when blocknumber is not null then 1 else 0 end) over (partition by documentref) as num_bn_notnull,
rank() over (partition by documentref
order by (case when blocknumber is not null then documentid end) desc nulls last
) as rnk
from t
) t
where num_bn_notnull = 0 or
rnk = 1;
或者,您可以使用exists
子句:
select t.*
from t
where not exists (select 1
from t t2
where t2.documentref = t.documentref and
t2.blocknumber is not null
) or
t.documentid = (select max(t2.documentid)
from t t2
where t2.documentref = t.documentref and
t2.blocknumber is not null
);
这可以利用(documentref, blocknumber, documentid)
上的索引。
实际上,通过对SQL语言的怪癖,我认为这同样有效:
select t.*
from t
where t.documentid >= any (select t2.documentid
from t t2
where t2.documentref = t.documentref and
t2.blocknumber is not null
order by t2.documentid
fetch first 1 row only
);
如果所有blocknumber
是NULL
,则子查询返回一个空集。根据定义,任何文档ID都符合空集上的条件。