从 SQL 到 SPL:将重复内容改成 NULL
某库表的前两列会同时出现重复值,比如下面第 2-3 条记录和第 1 条记录重复。
Column_A | Column_B | Column_C |
1 | AB | amount1 |
1 | AB | amount2 |
1 | AB | amount3 |
2 | OA | amount4 |
3 | OE | amount5 |
3 | OE | amount6 |
4 | DB | amount7 |
现在要将所有的重复值改成 null,换句话说,按前 2 个字段(或其中 1 个字段)分组后,只保留组内第一条不变,其他记录的前两个字段改成 null。
Column_A | Column_B | Column_C |
1 | AB | amount1 |
amount2 | ||
amount3 | ||
2 | OA | amount4 |
3 | OE | amount5 |
amount6 | ||
4 | DB | amount7 |
SELECT CASE a_rn WHEN 1 THEN column_a END AS column_a,
CASE b_rn WHEN 1 THEN column_b END AS column_b,
column_c
FROM (
SELECT column_a,
column_b,
column_c,
ROW_NUMBER() OVER (PARTITION BY column_a ORDER BY column_b, column_c)
AS a_rn,
ROW_NUMBER() OVER (PARTITION BY column_a, column_b ORDER BY column_c)
AS b_rn
FROM table_name)
SQL 没有天然行号包括组内行号,要用窗口函数生成后才能用,代码相对繁琐。SPL 内置行号,包括组内行号:https://try.esproc.com/splx?3Wp
A | |
1 | $select * from table_name.txt |
2 | =A1.group(Column_A).run(~.(if(#!=1,Column_A=Column_B=null))).conj() |
A1:加载数据。
A2:按 Column_A 分组,修改每组数据,当组内行号不为 1 时,将 Column_A 和 Column_B 改为 null;最后合并各组数据。# 表示组内行号。
如果数据量不大,也可以不分组合并,直接用当前记录的 Column_A 和前面所有的 Column_A 做比较,如果后者包含前者,则将 Column_A 和 Column_B 改为 null。代码如下:
=A1.run(if(Column_A[:-1].contain(Column_A), (Column_A=Column_B=null)))
[:-1] 表示从第 1 条记录到当前记录的上一条的集合。
跟练一下:
英文版 https://c.esproc.com/article/1744340880811