SparkSQL DataFrame去重:存在特定值时的过滤规则
SparkSQL 条件去重解决方案
需求说明
基于键列a和b执行以下过滤规则:
- 若某
(a,b)组合下存在c='N'的记录,仅保留该组合中c='N'的行 - 若某
(a,b)组合下无c='N'的记录,保留该组合所有行
输入数据
+-----------+----------+----------+----------+ |a |b |c |d | +-----------+----------+----------+----------+ | 123| abc| N| 2| | 123| abc| N| 4| | 123| abc| X| 3| | 456| def| K| 1| | 456| def| X| 4| +-----------+----------+----------+----------+
解决方案代码
通过窗口函数标记每组是否包含c='N'的记录,再执行过滤:
-- 创建原始数据临时视图 CREATE OR REPLACE TEMP VIEW original_data AS SELECT * FROM VALUES (123, 'abc', 'N', 2), (123, 'abc', 'N', 4), (123, 'abc', 'X', 3), (456, 'def', 'K', 1), (456, 'def', 'X', 4) AS t(a, b, c, d); -- 执行条件过滤 SELECT a, b, c, d FROM ( SELECT *, -- 标记当前(a,b)组是否存在c='N'的记录 MAX(CASE WHEN c = 'N' THEN 1 ELSE 0 END) OVER (PARTITION BY a, b) AS has_N FROM original_data ) t -- 过滤逻辑:组内有N则只留c=N的行,无N则全留 WHERE (has_N = 1 AND c = 'N') OR has_N = 0;
执行结果
+-----------+----------+----------+----------+ |a |b |c |d | +-----------+----------+----------+----------+ | 123| abc| N| 2| | 123| abc| N| 4| | 456| def| K| 1| | 456| def| X| 4| +-----------+----------+----------+----------+
逻辑解释
- 窗口函数
MAX(CASE WHEN c = 'N' THEN 1 ELSE 0 END) OVER (PARTITION BY a, b):对每个(a,b)组判断是否存在c='N'的记录,存在则has_N=1,否则为0 - 外层过滤条件:
- 当
has_N=1时,仅保留该组中c='N'的行 - 当
has_N=0时,保留该组所有行
- 当
内容的提问来源于stack exchange,提问作者C. Robinson
相关产品推荐
相关产品推荐

