sql - NTILE 仅适用于不为零的值

标签 sql oracle

我有一个包含许多零的列,我只想将非零值放入 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 查询相同的结果。

db<>fiddle

关于sql - NTILE 仅适用于不为零的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72228198/

相关文章:

mysql - 分组并选择最大对 SQL

oracle - MAXimo 工单总人工成本和总 Material 成本

sql - 查找或计算锦标赛的统计数据

java - JDBI Select In 使用流畅的界面(不是对象查询)

sql - 多部分标识符无法绑定(bind)sql

java - 如何在批量更新期间使 Hibernate 重用或重新创建临时表

sql - 数据库架构 : Why not create new table for each 'entity' ?

java - Java 中的 SQL 语法错误

oracle - Dapper with Oracle 传入 DbParameter

oracle - DBMS_REDEFINITION.start_redef_table 权限不足错误