如何解决SQL-有条件地联接和替换两个表之间的值
我有两个表,其中一个表保存“原始”数据,另一个表保存“更新”数据。更新后的数据仅包含来自第一个表的行的更正,但本质上是相同的。将这些数据分开存储是一项功能要求。
我要查询以下情况:
- 从第一个表中选择所有行
- 如果第二张表中有匹配的行(即
raw_d.primary_key_col_1 = edit_d.primary_key_col_1
和raw_d.primary_key_col_2 = edit_d.primary_key_col_2
时),我们将使用最新的(其中最新的是基于来自第二张桌子,而不是第一张桌子 - 否则,我们使用第一张表中的值。
注意:实际数据中还有更多“值”列。考虑下面的玩具示例,其中有两个表primary_key_col_3
和raw_d
,它们非常相似,如下所示:
edit_d
预期结果如下:
primary_key_col_1 | primary_key_col_2 | value_col_1 | value_col_2
-------------------------+-------------------------+-------------------+-------------------
src_1 | dest_1 | 0 | 1
src_2 | dest_2 | 5 | 4
src_3 | dest_3 | 2 | 2
src_4 | dest_4 | 6 | 3
src_5 | dest_5 | 9 | 9
primary_key_col_1 | primary_key_col_2 | primary_key_col_3 | value_col_1 | value_col_2
-------------------------+-------------------------+-------------------------+---------------------------------------
src_1 | dest_1 | 2020-05-09 | 7 | 0
src_2 | dest_2 | 2020-05-08 | 6 | 1
src_3 | dest_3 | 2020-05-07 | 5 | 2
src_1 | dest_1 | 2020-05-08 | 3 | 4
src_2 | dest_2 | 2020-05-09 | 2 | 5
我建议的解决方案是使用第二个表查询“每个组中最大的n个”,然后使用熊猫在第一个表的查询中“覆盖”行。
第一个查询只会从第一个表中获取数据:
primary_key_col_1 | primary_key_col_2 | value_col_1 | value_col_2
-------------------------+-------------------------+-------------------+-------------------
src_1 | dest_1 | 7 | 0
src_2 | dest_2 | 2 | 5
src_3 | dest_3 | 5 | 2
src_4 | dest_4 | 6 | 3
src_5 | dest_5 | 9 | 9
第二个选择“每组最大n”的查询如下:
SELECT * FROM raw_d
我计划像Replace column values based on another dataframe python pandas - better way?中那样合并数据。
有人知道更好的解决方案,最好仅使用SQL吗?作为参考,我将PostgreSQL和Pandas用作数据堆栈的一部分。
解决方法
从您的问题中我了解到,有两种方法可以解决此问题
1。使用FULL OUTER JOIN
with cte as (
select distinct on (primary_key_col_1,primary_key_col_2) * from edit_d
order by primary_key_col_1,primary_key_col_2,primary_key_col_3 desc
)
select
coalesce(t1.primary_key_col_1,t2.primary_key_col_1),coalesce(t1.primary_key_col_2,t2.primary_key_col_2),coalesce(t1.value_col_1,t2.value_col_1),coalesce(t1.value_col_2,t2.value_col_2)
from cte t1
full outer join raw_d t2
on t1.primary_key_col_1 = t2.primary_key_col_1
and t1.primary_key_col_2 = t2.primary_key_col_2
2。使用Union
select
distinct on (primary_key_col_1,primary_key_col_2)
primary_key_col_1,value_col_1,value_col_2
from (
select * from edit_d
union all
select primary_key_col_1,null as "primary_key_col_3",value_col_2 from raw_d
order by primary_key_col_1,primary_key_col_3 desc nulls last
)tab
,
我建议将需求表述为:
- 从第二个表中选择最新行
- 从第一个表中引入其他不匹配的行
这是一个union all
的{{1}}:
distinct on
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。