在 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;
我在 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;