我有一个表,我必须根据以下条件从中选择一些行。
- 如果存在多个具有相同 DocumentRef 的行,则在所有行的 BlockNumber 为空时选择所有行
- 如果存在多个具有相同 DocumentRef 的行,则仅选择 1 行(按 DocumentId asc 排序)且 BlockNumber 不为空
- 如果 DocumentRef 仅存在一行,则无论任何内容都选择它
我试图按 DocumentRef 对其进行分组,并使用having进行过滤,但having只能具有聚合函数。我想我必须提供多个用 OR 分隔的条件。请给我一些指导。
最佳答案
使用窗口函数:
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 都与空集上的条件匹配。
关于sql - 根据多个条件选择行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60141317/