我有一个包含许多零的列,我只想将非零值放入 N 组(大约)相等的大小中。所有零值都应该得到组号 0。有没有一种优雅的方法来做到这一点?
我的第一个方法是使用下面代码中的 ntile_v2
,但这样 bin 编号不以 1 开头,并且我不会得到 N 个 bin。
with sample_data as
(select
rownum as id,
case when rownum <= 50 then 0 else rownum end as value
from xmltable('1 to 100')
)
select
id,
value,
ntile(50) over (order by value) as ntile_v1,
case when value = 0 then 0 else ntile(50) over (order by value) end as ntile_v2
from sample_data
order by id;
一种解决方案是将非零值放入单独的 CTE 中,计算其中的图 block ,然后连接回来:
with sample_data as
(select
rownum as id,
case when rownum <= 50 then 0 else rownum end as value
from xmltable('1 to 100')
)
, sample_data_not_zero as
(select
id,
value,
ntile(50) over (order by value) as ntile_v3
from sample_data
where value <> 0
)
select
sd.id,
sd.value,
nvl(sdnz.ntile_v3, 0) as ntile_v3
from
sample_data sd
left outer join
sample_data_not_zero sdnz on sd.id = sdnz.id
order by id;
不幸的是,我必须为许多不同的列计算这个值,我想知道是否有更短的解决方案。
最佳答案
除了当前的 case 表达式之外,您还可以根据零与非零对 ntile
进行分区:
case
when value = 0 then 0
else ntile(50) over (partition by case when value = 0 then 0 else 1 end order by value)
end as ntile_v3
这似乎得到了与您的 union
查询相同的结果。
关于sql - NTILE 仅适用于不为零的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72228198/