如何在PROC SQL/SAS中基于特定列条件合并两个数据集?
问题描述
我拥有两个数据集table_A和table_B,结构与数据如下所示。需要基于特定列条件正确合并得到目标输出,但直接执行连接操作的结果不符合预期。请提供SAS或PROC SQL的实现方法。
table_A
| user_cd | item_nbr | product_cd | part_cd | line_grp | from_geo | to_geo | between_geo |
|---|---|---|---|---|---|---|---|
| 01 | 255258 | 54147 | 1 | 29 | AL | AZ | |
| 01 | 255258 | 54147 | 1 | 29 | PR | ||
| 01 | 255258 | 54147 | 1 | 29 | WA | ||
| 01 | 255258 | 54147 | 1 | 29 | NV | ||
| 01 | 255258 | 54147 | 2 | 30 | NY | NJ | |
| 01 | 255258 | 54147 | 2 | 30 | PA | ||
| 03 | 999999 | 22222 | 1 | 60 | WY | AZ | |
| 03 | 999999 | 22222 | 1 | 60 | TX | TX | |
| 03 | 999999 | 22222 | 1 | 60 | CA | ||
| 03 | 999999 | 22222 | 2 | 99 | NJ | ||
| 03 | 999999 | 22222 | 2 | 99 | CA | ||
| 03 | 999999 | 22222 | 2 | 99 | ND |
table_B
| user_cd | item_nbr | product_cd | part_cd | line_grp | oprtr_cd | oprtr_typ | num_value | zone_a | zone_b | zone_c |
|---|---|---|---|---|---|---|---|---|---|---|
| 01 | 255258 | 54147 | 1 | 29 | A | $ | 140 | TRN | 1 | 1 |
| 01 | 255258 | 54147 | 1 | 29 | B | % | 15 | TRN | 1 | 1 |
| 01 | 255258 | 54147 | 1 | 29 | C | % | 15 | TRN | 1 | 1 |
| 01 | 255258 | 54147 | 1 | 29 | A | $ | 200 | TRN | 1 | 2 |
| 01 | 255258 | 54147 | 1 | 29 | B | % | 25 | TRN | 1 | 2 |
| 01 | 255258 | 54147 | 1 | 29 | C | % | 25 | TRN | 1 | 2 |
| 01 | 255258 | 54147 | 1 | 29 | A | $ | 175 | TRN | 2 | 5 |
| 01 | 255258 | 54147 | 1 | 29 | B | % | 33 | TRN | 2 | 5 |
| 01 | 255258 | 54147 | 1 | 29 | C | % | 38 | TRN | 2 | 5 |
| 01 | 255258 | 54147 | 2 | 30 | A | $ | 140 | PQR | 37 | 1 |
| 01 | 255258 | 54147 | 2 | 30 | B | % | 15 | PQR | 37 | 1 |
| 01 | 255258 | 54147 | 2 | 30 | C | % | 15 | PQR | 37 | 1 |
| 01 | 255258 | 54147 | 2 | 30 | A | $ | 200 | PQR | 41 | 8 |
| 01 | 255258 | 54147 | 2 | 30 | B | % | 25 | PQR | 41 | 8 |
| 01 | 255258 | 54147 | 2 | 30 | C | % | 25 | PQR | 41 | 8 |
| 03 | 999999 | 22222 | 1 | 60 | A | $ | 100 | TRN | 1 | 1 |
| 03 | 999999 | 22222 | 1 | 60 | B | % | 15 | TRN | 1 | 1 |
| 03 | 999999 | 22222 | 1 | 60 | C | % | 27 | TRN | 1 | 1 |
| 03 | 999999 | 22222 | 1 | 60 | A | $ | 100 | ABC | 1 | 2 |
| 03 | 999999 | 22222 | 1 | 60 | B | % | 15 | ABC | 1 | 2 |
| 03 | 999999 | 22222 | 1 | 60 | C | % | 27 | ABC | 1 | 2 |
| 03 | 999999 | 22222 | 2 | 99 | A | $ | 100 | TRN | 1 | 1 |
| 03 | 999999 | 22222 | 2 | 99 | B | % | 15 | TRN | 1 | 1 |
| 03 | 999999 | 22222 | 2 | 99 | C | % | 27 | TRN | 1 | 1 |
| 03 | 999999 | 22222 | 2 | 99 | A | $ | 100 | ABC | 1 | 2 |
| 03 | 999999 | 22222 | 2 | 99 | B | % | 15 | ABC | 1 | 2 |
| 03 | 999999 | 22222 | 2 | 99 | C | % | 27 | ABC | 1 | 2 |
解决方案
1. SAS 数据步实现
先按分组键对两个数据集排序,再通过一对一合并(按分组键),确保每个table_A的行匹配对应分组的所有table_B行:
/* 对table_A和table_B按分组列排序 */ proc sort data=table_A; by user_cd item_nbr product_cd part_cd line_grp; run; proc sort data=table_B; by user_cd item_nbr product_cd part_cd line_grp; run; /* 合并数据集 */ data final_table; merge table_A table_B; by user_cd item_nbr product_cd part_cd line_grp; run;
2. PROC SQL 实现
通过内连接,指定分组列作为连接条件,确保每个table_A的行与同分组的所有table_B行匹配:
proc sql; create table final_table as select a.*, b.oprtr_cd, b.oprtr_typ, b.num_value, b.zone_a, b.zone_b, b.zone_c from table_A a inner join table_B b on a.user_cd = b.user_cd and a.item_nbr = b.item_nbr and a.product_cd = b.product_cd and a.part_cd = b.part_cd and a.line_grp = b.line_grp; quit;
这两种方法都能确保table_A中同一分组(user_cd/item_nbr/product_cd/part_cd/line_grp)的每一行,都匹配table_B中对应分组的所有行,从而得到符合预期的合并结果。
内容的提问来源于stack exchange,提问作者Rogue258
相关产品推荐
相关产品推荐

