如何提取两表中各自独有的账户数据(SAS/SQL实现方法)
两表独有账户数据查询实现方案
需求说明:表A、表B均以
账号为账户唯一标识字段,需剔除两表共有账户,分别提取仅在表A存在、表B无匹配的账户数据,以及仅在表B存在、表A无匹配的账户数据。
SQL 通用实现
以下写法兼容MySQL、PostgreSQL、SQL Server、Hive等主流SQL引擎,优先推荐前两种容错性、性能更优的写法:
NOT EXISTS写法(主键字段有索引时性能最优)
-- 查询仅在表A存在的账户 SELECT a.* FROM 表A a WHERE NOT EXISTS ( SELECT 1 FROM 表B b WHERE b.账号 = a.账号 ); -- 查询仅在表B存在的账户 SELECT b.* FROM 表B b WHERE NOT EXISTS ( SELECT 1 FROM 表A a WHERE a.账号 = b.账号 );
- 左连接判空写法(逻辑直观,适合多字段关联场景)
-- 查询仅在表A存在的账户 SELECT a.* FROM 表A a LEFT JOIN 表B b ON a.账号 = b.账号 WHERE b.账号 IS NULL; -- 查询仅在表B存在的账户 SELECT b.* FROM 表B b LEFT JOIN 表A a ON b.账号 = a.账号 WHERE a.账号 IS NULL;
注意:不推荐使用NOT IN写法,若子查询返回的账号字段存在NULL值,会导致查询结果整体异常,容错性差。
SAS 实现
SAS针对数据集比对提供了原生高效的实现方式,大数据量下优先使用DATA步合并方案:
- DATA步MERGE写法(性能最优,适合百万级以上大表)
使用前需确保两个数据集已按关联主键账号排序,未排序可先执行排序过程:
/* 按主键排序,已排序的数据集可跳过该步骤 */ PROC SORT DATA=表A OUT=tmp_A; BY 账号; RUN; PROC SORT DATA=表B OUT=tmp_B; BY 账号; RUN; /* 合并拆分输出结果 */ DATA only_A /* 存储仅在表A存在的账户 */ only_B /* 存储仅在表B存在的账户 */ ; MERGE tmp_A(IN=in_a) /* 打标:记录来自表A时in_a=1 */ tmp_B(IN=in_b) /* 打标:记录来自表B时in_b=1 */ ; BY 账号; IF in_a=1 AND in_b=0 THEN OUTPUT only_A; IF in_b=1 AND in_a=0 THEN OUTPUT only_B; /* 两表共有的in_a=1且in_b=1的记录默认不输出,直接剔除 */ RUN;
- PROC SQL写法(语法和通用SQL一致,适合熟悉SQL的用户)
PROC SQL; CREATE TABLE only_A AS SELECT a.* FROM 表A a WHERE NOT EXISTS (SELECT 1 FROM 表B b WHERE b.账号 = a.账号); CREATE TABLE only_B AS SELECT b.* FROM 表B b WHERE NOT EXISTS (SELECT 1 FROM 表A a WHERE a.账号 = b.账号); QUIT;
扩展:如果需要把两类独有数据汇总到同一张表,只需在查询时新增来源标记字段(比如'A' AS data_source),再用UNION ALL拼接两个查询结果即可。
内容的提问来源于stack exchange,提问作者JDS
相关产品推荐
相关产品推荐

