比较列和重复数据删除
Compare columns and dedupe
请看下面table,我想创建一个不同的电话号码列表,GROUP 号码的排名需要优先从 1-4 降序排列。该示例应导致 ID 4、9、10(突出显示为红色 x)被删除,因为它们共享重复的电话号码但在优先级较低的 GROUP 中。
我已经成功地通过许多步骤完成了这项工作并创建了一个代理键,但我希望有人能告诉我如何一步完成,以提高效率(并提高我的 SQL).
在 SAS9 中,我有一个 coalescec 函数,我可以在其中创建一个新变量并指示优先级 - 但我知道 SQL 中没有这样的函数。
https://documentation.sas.com/doc/en/vdmmlcdc/8.1/ds2ref/n0crpo0xd76wb3n1poba9wmu1a6q.htm
请参阅下方 SQL 中的模拟数据
CREATE TABLE MT_TEMP_TEL2 (
ID INT NOT NULL,
GROUP INT NOT NULL,
TEL1 VARCHAR(11),
TEL2 VARCHAR(11),
TEL3 VARCHAR(11),
TEL4 VARCHAR(11)
);
INSERT INTO MT_TEMP_TEL2
VALUES
(1,4,"79000000000","","",""),
(2,1,"12111111111","79999999999","",""),
(3,1,"","13842222222","",""),
(4,2,"","","78888888888","12111111111"),
(5,3,"","73333333333","",""),
(6,1,"15278888888","","",""),
(7,2,"","","71111111111",""),
(8,4,"","13843333333","","72222222222"),
(9,4,"","73333333333","",""),
(10,3,"75555555555","","12155555555","13842222222");
这是如上所述的预期结果,我们现在删除了第 4、9 和 10 行
ID
群组
电话 1
电话 2
电话 3
电话 4
1
4
79000000000
2
1
12111111111
79999999999
3
1
13842222222
5
3
73333333333
6
1
15278888888
7
2
71111111111
8
4
13843333333
72222222222
我在提到 coalesce
时假设目标是将 4 列压缩到一个值列表中,预期结果示例现在表明情况并非如此。
有几种方法可以解决这个问题,一种是使用window functions
为每个重复出现的值分配一个序号;为此,必须将这些值合并到一个列表中,您可以使用 union
,其结果然后由组合值 partitioned
和每个 duplicate 获取连续的行号。然后就是只保留值为 1 的那些。
with Alltel as (
select id, [group], tel1 from MT_TEMP_TEL2 union all
select id, [group], tel2 from MT_TEMP_TEL2 union all
select id, [group], tel3 from MT_TEMP_TEL2 union all
select id, [group], tel4 from MT_TEMP_TEL2
), rn as (
select id, tel1, Row_Number() over (partition by tel1 order by [group]) n
from alltel
where tel1 !=''
)
select *
from MT_TEMP_TEL2 t
where not exists (select * from rn where rn.id=t.id and rn.n>1)
请看下面table,我想创建一个不同的电话号码列表,GROUP 号码的排名需要优先从 1-4 降序排列。该示例应导致 ID 4、9、10(突出显示为红色 x)被删除,因为它们共享重复的电话号码但在优先级较低的 GROUP 中。
我已经成功地通过许多步骤完成了这项工作并创建了一个代理键,但我希望有人能告诉我如何一步完成,以提高效率(并提高我的 SQL).
在 SAS9 中,我有一个 coalescec 函数,我可以在其中创建一个新变量并指示优先级 - 但我知道 SQL 中没有这样的函数。
https://documentation.sas.com/doc/en/vdmmlcdc/8.1/ds2ref/n0crpo0xd76wb3n1poba9wmu1a6q.htm
请参阅下方 SQL 中的模拟数据
CREATE TABLE MT_TEMP_TEL2 (
ID INT NOT NULL,
GROUP INT NOT NULL,
TEL1 VARCHAR(11),
TEL2 VARCHAR(11),
TEL3 VARCHAR(11),
TEL4 VARCHAR(11)
);
INSERT INTO MT_TEMP_TEL2
VALUES
(1,4,"79000000000","","",""),
(2,1,"12111111111","79999999999","",""),
(3,1,"","13842222222","",""),
(4,2,"","","78888888888","12111111111"),
(5,3,"","73333333333","",""),
(6,1,"15278888888","","",""),
(7,2,"","","71111111111",""),
(8,4,"","13843333333","","72222222222"),
(9,4,"","73333333333","",""),
(10,3,"75555555555","","12155555555","13842222222");
这是如上所述的预期结果,我们现在删除了第 4、9 和 10 行
ID | 群组 | 电话 1 | 电话 2 | 电话 3 | 电话 4 |
---|---|---|---|---|---|
1 | 4 | 79000000000 | |||
2 | 1 | 12111111111 | 79999999999 | ||
3 | 1 | 13842222222 | |||
5 | 3 | 73333333333 | |||
6 | 1 | 15278888888 | |||
7 | 2 | 71111111111 | |||
8 | 4 | 13843333333 | 72222222222 |
我在提到 coalesce
时假设目标是将 4 列压缩到一个值列表中,预期结果示例现在表明情况并非如此。
有几种方法可以解决这个问题,一种是使用window functions
为每个重复出现的值分配一个序号;为此,必须将这些值合并到一个列表中,您可以使用 union
,其结果然后由组合值 partitioned
和每个 duplicate 获取连续的行号。然后就是只保留值为 1 的那些。
with Alltel as (
select id, [group], tel1 from MT_TEMP_TEL2 union all
select id, [group], tel2 from MT_TEMP_TEL2 union all
select id, [group], tel3 from MT_TEMP_TEL2 union all
select id, [group], tel4 from MT_TEMP_TEL2
), rn as (
select id, tel1, Row_Number() over (partition by tel1 order by [group]) n
from alltel
where tel1 !=''
)
select *
from MT_TEMP_TEL2 t
where not exists (select * from rn where rn.id=t.id and rn.n>1)