Oracle查询中如何按类别生成依赖res值的新列X
解决方案
你可以使用窗口函数来实现按categ分组处理res列生成目标列X。以下提供两种符合不同需求的实现方式:
需求1:同类别下只要存在res='S',所有行的X都显示'S'
核心逻辑是按categ分组,提取组内res的非空有效值,让同组所有行共享该值:
SELECT id_t, val, categ, res, MAX(res) OVER (PARTITION BY categ) AS X FROM ( -- 你的原始查询语句 select 1 id_t, 'Book 1' val, 'C1' categ, 'S' res from dual union select 2 id_t, 'Book 2' val, 'C1' categ, null res from dual union select 3 id_t, 'Book 3' val, 'C1' categ, null res from dual union select 4 id_t, 'Book 4' val, 'C2' categ, 'S' res from dual union select 5 id_t, 'Book 5' val, 'C3' categ, 'S' res from dual union select 6 id_t, 'Book 6' val, 'C3' categ, null res from dual ) t;
逻辑说明:MAX(res)会自动忽略null,只要组内有'S',分组后的最大值就是'S',正好让同组所有行的X统一为'S'。
需求2:同类别下仅第一个res='S'的行显示'S',其余行X为null
这个逻辑和你给出的示例中res列的分布完全匹配:
SELECT id_t, val, categ, res, CASE WHEN ROW_NUMBER() OVER (PARTITION BY categ ORDER BY CASE WHEN res='S' THEN 1 ELSE 2 END) = 1 AND res='S' THEN 'S' ELSE null END AS X FROM ( -- 你的原始查询语句 select 1 id_t, 'Book 1' val, 'C1' categ, 'S' res from dual union select 2 id_t, 'Book 2' val, 'C1' categ, null res from dual union select 3 id_t, 'Book 3' val, 'C1' categ, null res from dual union select 4 id_t, 'Book 4' val, 'C2' categ, 'S' res from dual union select 5 id_t, 'Book 5' val, 'C3' categ, 'S' res from dual union select 6 id_t, 'Book 6' val, 'C3' categ, null res from dual ) t;
逻辑说明:先按categ分组,把res='S'的行排在组内最前面,然后给组内行编号,仅第一个且res='S'的行赋值'S',其余行留空。
内容的提问来源于stack exchange,提问作者Fernando Palomeque
相关产品推荐
相关产品推荐

