Oracle PLSQL按nb1累计分配co1-co5列值的实现求助
Oracle SQL:按累计nb1值分配co列数据到fin/fin2列
核心逻辑实现
基于需求——按nb1的累计值(nb2)依次从co1到co5分配数值,超出当前co列范围则转入下一列,若co列值大于当前累计需求则仅取覆盖需求的量——以下是完整的Oracle SQL解决方案:
WITH calc AS ( SELECT t.*, -- 计算当前行对应的累计nb1增量(即需要分配的总量) NVL(nb2 - LAG(nb2) OVER (ORDER BY id), nb2) AS current_need, -- 计算所有co列的总和,用于快速判断是否能覆盖需求 co1 + co2 + co3 + co4 + co5 AS total_co FROM your_table t ) SELECT id, nb1, nb2, co1, co2, co3, co4, co5, -- fin:按规则计算的总分配量 CASE WHEN current_need <= co1 THEN current_need WHEN current_need <= co1 + co2 THEN current_need WHEN current_need <= co1 + co2 + co3 THEN current_need WHEN current_need <= co1 + co2 + co3 + co4 THEN current_need ELSE LEAST(co1 + co2 + co3 + co4 + co5, current_need) END AS fin, -- fin2:标记最后用到的co列(可根据需求调整为其他逻辑) CASE WHEN current_need <= co1 THEN 'co1' WHEN current_need <= co1 + co2 THEN 'co2' WHEN current_need <= co1 + co2 + co3 THEN 'co3' WHEN current_need <= co1 + co2 + co3 + co4 THEN 'co4' ELSE 'co5' END AS fin2, -- 可选:单独查看每个co列的分配明细 LEAST(co1, current_need) AS co1_allocated, LEAST(GREATEST(current_need - co1, 0), co2) AS co2_allocated, LEAST(GREATEST(current_need - co1 - co2, 0), co3) AS co3_allocated, LEAST(GREATEST(current_need - co1 - co2 - co3, 0), co4) AS co4_allocated, LEAST(GREATEST(current_need - co1 - co2 - co3 - co4, 0), co5) AS co5_allocated FROM calc ORDER BY id;
代码说明
CTE
calc部分current_need:计算当前行需要分配的累计增量——若为第一行则直接取nb2,否则取当前nb2与上一行nb2的差值,确保只处理当前行新增的累计需求。total_co:快速判断所有co列的总和是否能覆盖当前需求,便于后续逻辑简化。
主查询部分
fin:按co1→co2→co3→co4→co5的顺序分配数值,直到覆盖current_need或用完所有co列的值。fin2:标记分配时最后用到的co列,用于追踪分配来源(若你的fin2是其他分配目标,可修改CASE逻辑,比如将co4-co5的分配量单独放入fin2)。- 分配明细列:
co1_allocated到co5_allocated直观展示每个co列实际分配的数值,方便验证逻辑是否符合预期。
分组累计场景调整
如果你的nb2是按分组(比如group_id)计算的累计值,只需在LAG函数的OVER子句中添加分组条件:
NVL(nb2 - LAG(nb2) OVER (PARTITION BY group_id ORDER BY id), nb2) AS current_need
内容的提问来源于stack exchange,提问作者Green
相关产品推荐
相关产品推荐

