You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

合并含空值行并保留唯一组合的SQL解决方案咨询

合并含空值的行并保留唯一组合的解决方案

我明白你的痛点了——想用窗口函数按组取最大值来合并行,但空值打乱了分区逻辑,导致没法得到想要的唯一组合。先看看你的原查询问题出在哪:

SELECT SALES_ORG ,MAX(MATERIAL) OVER (PARTITION BY SALES_ORG,MATERIAL ORDER BY MATERIAL) as MATERIAL ,MAX(MGROUP) OVER (PARTITION BY SALES_ORG,MATERIAL,MGROUP ORDER BY MGROUP ) as MGROUP ,MAX(SERVICE) OVER (PARTITION BY SALES_ORG,MATERIAL,MGROUP,SERVICE ORDER BY SERVICE ) as SERVICE FROM SALES

你把所有字段都塞进了PARTITION BY里,这意味着只有当所有字段完全一致(包括空值的位置)时,行才会被分到同一分区。空值的行自然会被单独划分,MAX函数根本没机会合并它们。

下面给你几个实用的解决思路:

方案1:GROUP BY核心唯一键 + 聚合函数(最推荐)

如果你的唯一组合是基于SALES_ORG和MATERIAL(这两个字段能确定一组唯一数据),直接按这两个字段分组,对其他字段用MAX提取非空值就行——MAX会自动忽略空值,只返回分组内的有效非空值:

SELECT
    SALES_ORG,
    MATERIAL,
    MAX(MGROUP) AS MGROUP,
    MAX(SERVICE) AS SERVICE
FROM SALES
GROUP BY SALES_ORG, MATERIAL

举个例子:如果同一SALES_ORG+MATERIAL下有两行,一行MGROUP为空、SERVICE有值,另一行MGROUP有值、SERVICE为空,合并后会得到两个字段都有值的唯一行。

方案2:处理空值后再分组(核心键可能为空时)

如果MATERIAL也可能为空,且你需要把同一SALES_ORG下空MATERIAL的行合并成一组,可以用COALESCE给空值生成一个临时分组键,避免空值被单独分区:

SELECT
    SALES_ORG,
    -- 分组后如果有非空的MATERIAL就返回,否则保留空值
    CASE WHEN MAX(MATERIAL) IS NOT NULL THEN MAX(MATERIAL) ELSE NULL END AS MATERIAL,
    MAX(MGROUP) AS MGROUP,
    MAX(SERVICE) AS SERVICE
FROM SALES
GROUP BY SALES_ORG,
         -- 给空MATERIAL分配和SALES_ORG绑定的临时键,确保同组
         COALESCE(MATERIAL, 'TEMP_GROUP_' || SALES_ORG)

方案3:用窗口函数去重(不想用GROUP BY时)

如果你更倾向于用窗口函数,可以先按核心键分区提取非空值,再用DISTINCT去重得到唯一组合:

SELECT DISTINCT
    SALES_ORG,
    MAX(MATERIAL) OVER (PARTITION BY SALES_ORG, COALESCE(MATERIAL, 'TEMP_GROUP_' || SALES_ORG)) AS MATERIAL,
    MAX(MGROUP) OVER (PARTITION BY SALES_ORG, COALESCE(MATERIAL, 'TEMP_GROUP_' || SALES_ORG)) AS MGROUP,
    MAX(SERVICE) OVER (PARTITION BY SALES_ORG, COALESCE(MATERIAL, 'TEMP_GROUP_' || SALES_ORG)) AS SERVICE
FROM SALES

这个思路和方案2类似,只是用窗口函数替代了GROUP BY,最后通过DISTINCT去掉重复的合并行。

内容的提问来源于stack exchange,提问作者Mani

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 12:08:11