如何从单源多值数据集中为每个源仅选取一行数据
解决方案
要实现每个Source仅保留一行数据,核心是通过分组后选择每组内特定行的方式,而非简单去重或关联。以下是几种常见SQL实现方式,可根据你的具体需求选择:
1. 取每组的第一行(按默认顺序)
如果只需每个Source保留任意一行(比如示例中Tester取第一个值),可以用窗口函数ROW_NUMBER()给每组内的行编号,再筛选编号为1的行:
SELECT Source, Values FROM ( SELECT Source, Values, -- 按Source分组,给每组内的行编号,ORDER BY可指定排序规则 ROW_NUMBER() OVER (PARTITION BY Source ORDER BY (SELECT NULL)) AS row_num FROM your_table_name ) AS grouped_data WHERE row_num = 1;
注:
ORDER BY (SELECT NULL)表示使用数据库默认的行顺序,若有时间戳、ID等排序字段,替换成该字段更可靠(比如ORDER BY id ASC)。
2. 优先取NULL值(对应示例中Tester3的场景)
如果需要优先保留每组中的NULL值,可调整窗口函数的排序规则,把NULL排在最前面:
SELECT Source, Values FROM ( SELECT Source, Values, ROW_NUMBER() OVER ( PARTITION BY Source ORDER BY CASE WHEN Values IS NULL THEN 0 ELSE 1 END ) AS row_num FROM your_table_name ) AS grouped_data WHERE row_num = 1;
3. 按特定条件选择行(比如示例中Tester2取指定值)
如果需要按Values的特定规则选择(比如包含关键词、特定位置的值),可以在排序中加入自定义条件:
SELECT Source, Values FROM ( SELECT Source, Values, ROW_NUMBER() OVER ( PARTITION BY Source -- 这里示例是优先保留包含"sampled"的行 ORDER BY CASE WHEN Values LIKE '%sampled%' THEN 0 ELSE 1 END ) AS row_num FROM your_table_name ) AS grouped_data WHERE row_num = 1;
你之前尝试的DISTINCT会保留所有唯一的(Source, Values)组合,无法实现每个Source一行;JOIN和UNION也不是处理这类分组选行场景的正确方式,窗口函数才是这类需求的常规解决方案。
内容的提问来源于stack exchange,提问作者Foxxy
相关产品推荐
相关产品推荐

