我想从数据库中选择具有结果数量限制的行。我总是希望返回最少数量的结果,即使这意味着忽略了我的其他标准,我也不希望有超过最大数量。
我当前的查询如下所示:
(SELECT * FROM Athletes WHERE Height > 72
FETCH FIRST 10 ROWS ONLY)
UNION
(SELECT * FROM Athletes
ORDER BY Height DESC
FETCH FIRST 3 ROWS ONLY)
FETCH FIRST 10 ROWS ONLY
这里的想法是我想找到所有高于6英尺(72")的运动员。如果超过十个,我只想要其中的十个,但如果少于三个,我想要三个最高的运动员,即使有些人不到六英尺。
这对我的测试数据很好,但是我想摆脱UNION
的生产。如何在没有UNION
或DISTINCT
之类的性能消耗位的情况下重写此内容?
答案 0 :(得分:0)
一种方法是使用CTE:
with ten as (
SELECT *
FROM Athletes
WHERE Height > 72
FETCH FIRST 10 ROWS ONLY
)
select t.*
from ten
where (select count(*) from ten) >= 3
union all
select a.*
from atheletes
where (select count(*) from ten) < 3
order by height desc
fetch first 3 rows only;
我认为这应该非常快,因为计算表中的10行应该非常快并且没有重复消除。
编辑:
另一种方法使用窗口函数,但可能性能较差:
select a.*
from (select a.*,
sum(case when height > 72 then 1 else 0 end) over () as num_gt72,
row_number() over (order by height desc) as seqnum
from (select a.*
from athletes a
order by height desc
fetch first 10 rows only
) a
) a
where seqnum <= num_gt72 or
(seqnum <= 3 and num_gt72 < 3);