在 SAS 中使用 proc SQL 在所有可能的匹配变量上合并 3 个表

Merging 3 tables on all possible matching variables using proc SQL in SAS

我在 SAS 中有 3 个数据集:

main_1

ID Rep Dose Response
1   2   34    567
1   1   45    756
2   1   35    456
3   1   56    345

main_2

ID Rep Hour Day
1   1   89  157
2   1   62  365
3   1   12  689

main_3

ID  Rep  Town   City
1   1    3268   151643
2   1    2574   165435
3   1    1254   135435
2   2    1563   135435

将表导入 SAS 后,我目前有以下 proc SQL 代码(我正在学习,很抱歉它太糟糕了)合并表,以便每个 ID 和 Rep 包含所有相关信息。我似乎无法有效地合并所有 3 个表,因为 main_1 不包括所有可能的 ID 和 Rep 组合(实际上 none 包括):

  PROC SQL; 
        create table merged_sql_2 as 
        select A.*,
               B.hour,
               B.day,
               C.Town,
               C.City
        from main_1 as A 
        LEFT JOIN main_2 as B 
            on A.ID = B.ID
            and A.Rep = B.Rep
        LEFT JOIN main_3 as C 
            on A.ID = C.ID
            and A.Rep = C.Rep;
    QUIT;

生成以下内容,但缺少 1 个观察结果:

   ID   Rep Dose    Response    Hour    Day   Town    City
    1    1   45       756        89     157   3268   151643
    1    2   34       567        -       -      -      -
    2    1   35       456        62     365   2574   165435
    3    1   56       345        12     689   1254   135435

我需要合并所有可能的匹配项以实现以下目标:

ID  Rep Dose    Response    Hour    Day   Town    City
1    1   45       756        89     157   3268   151643
1    2   34       567        -       -      -      -
2    1   35       456        62     365   2574   165435
2    2   -         -         -       -    1563   135435
3    1   56       345        12     689   1254   135435

如果上面的代码是完全错误的方法,我很乐意学习其他 SQL 替代方法!

非常感谢。

您需要使用 FULL JOIN 而不是 LEFT JOIN

试试这个:

PROC SQL; 
    create table merged_sql_2 as 
    select coalesce(a.id,b.id,c.id) as id,
           coalesce(a.rep,b.rep,c.rep) as rep,
           a.dose,
           a.response,
           B.hour,
           B.day,
           C.Town,
           C.City
    from main_1 as A 
    FULL JOIN main_2 as B 
        on A.ID = B.ID
        and A.Rep = B.Rep
    FULL JOIN main_3 as C 
        on A.ID = C.ID
        and A.Rep = C.Rep;
QUIT;

COALESCE() 函数从列表中选取第一个非空值。这使您可以保留来自任何贡献一行的 table 的键。

使用完全自然连接也有效:

proc sql;
    create table new as 
    select rep, dose, response, hour, day, town, city from 
    Main_1 natural full join Main_2 natural full join Main_3 
 ;
quit;