PostgreSQL 相当于 Pandas 外部合并

Posted

技术标签:

【中文标题】PostgreSQL 相当于 Pandas 外部合并【英文标题】:PostgreSQL equivalent of Pandas outer merge 【发布时间】:2021-05-31 16:03:37 【问题描述】:

我试图在 Postgres 中做相当于 Pandas 的外部合并,以便外部合并两个表。

df_1 包含这些数据:

df_2 包含这些数据:

所以表 df_1df_2 多了一列 (random_id)。此外,df_1df_2 中都存在 job_id 1711418 和 worker_id 45430

如果我在 Pandas 中使用“外部合并”方法: df_1.merge(df_2, on=['job_id', 'worker_id'], how='outer'),我会得到如下所示的理想结果:

但是,我找不到与 Pandas 外部合并方法等效的 SQL (postgres)。

我已尝试运行以下查询:

select *
from df_1
full outer join df_2
   on df_1.job_id = df_2.job_id 
  and df_1.worker_id = df_2.worker_id

但是,结果生成了 2 个额外的重复列,称为 job_id_duplicate_column_name_1worker_id_duplicate_column_name_1,我不想要:

谁能帮忙推荐一种查询方法,可以实现与 Pandas 中的外部合并方法相同的功能?

【问题讨论】:

样本数据最好显示为formatted text。请参阅here,了解有关如何创建漂亮表格的一些提示。 默认 Pandas 合并/连接是“自然”的 SQL 连接。在使用功能之前阅读文档。 这能回答你的问题吗? Difference between natural join and inner join @philipxy,自然连接在我的情况下不起作用,因为它只连接匹配的记录。在我的用例中,df_1 和 df_2 之间有一些不同的记录,我想在结果中保留所有这些记录。 我的意思是自然完全连接。我错过了我发现的问答只针对自然内部与普通内部,而不是针对内部和外部的自然与普通。您的表的特殊情况意味着您可以进行自然的右连接。您还需要将 NULL 映射到 NaN。在特殊情况和 NaN 之间,您可能希望在接受的答案中使用 UNION 等。我专注于自然与朴素;我目前不确定这是否是您真正想要的结果。 PS请use text, not images/links, for text--including tables & ERDs. 【参考方案1】:

这在我看来像是一个 UNION,而不是一个 JOIN:

select job_id, worker_id, random_id
from df_1
union all
select job_id, worker_id, 'NaN'
from df_2 d2
where not exists (select *
                  from df_1 d1
                  where d1.job_id = d2.job_id
                    and d1.worker_id = d2.worker_id)

联合的第二部分返回 df_2 中不存在于 df_1 中的所有行

另一种方法是使用 EXCEPT 从 df_2 获取 df_1 中不存在的行

select job_id, worker_id, random_id
from df_1
union all
select job_id, worker_id, 'NaN'
from 
(
  select job_id, worker_id
  from df_2 d2
  except
  select job_id, worker_id
  from df_1
) t

Online example

【讨论】:

谢谢@a_horse_with_no_name!您的建议按预期工作。我将花一些时间来了解有关此方法的更多信息。

以上是关于PostgreSQL 相当于 Pandas 外部合并的主要内容,如果未能解决你的问题,请参考以下文章

postgresql友好地返回不是'PANDAS'的多行表[重复]

使用 sqlalchemy 从 PostgreSQL 查询返回 Pandas 数据框

将 1100 万行从 Postgresql 导入到 Pandas/Python

python postgresql从pandas数据框创建数据库并填充表

pandas将dataframe中的年月日数据列合并成完整日期字符串并使用to_datetime将字符串格式转化为日期格式

PostgreSQL外部数据