Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python SQL-在两个表之间有条件地联接和替换值_Python_Sql_Database_Pandas_Postgresql - Fatal编程技术网

Python SQL-在两个表之间有条件地联接和替换值

Python SQL-在两个表之间有条件地联接和替换值,python,sql,database,pandas,postgresql,Python,Sql,Database,Pandas,Postgresql,我有两个表,其中一个保存“原始”数据,另一个保存“更新”数据。更新后的数据只包含第一个表中的行的更正,但本质上是相同的。该数据单独存储是一项功能要求 我需要具有以下条件的查询: 从第一个表中选择所有行 如果第二个表中有一个匹配行(即当raw\u d.primary\u key\u col\u 1=edit\u d.primary\u col\u 1和raw\u d.primary\u key\u col\u 2=edit\u d.primary\u key\u col\u 2时,我们使用第二个

我有两个表,其中一个保存“原始”数据,另一个保存“更新”数据。更新后的数据只包含第一个表中的行的更正,但本质上是相同的。该数据单独存储是一项功能要求

我需要具有以下条件的查询:

  • 从第一个表中选择所有行
  • 如果第二个表中有一个匹配行(即当
    raw\u d.primary\u key\u col\u 1=edit\u d.primary\u col\u 1
    raw\u d.primary\u key\u col\u 2=edit\u d.primary\u key\u col\u 2
    时,我们使用第二个表中最新的值(其中最新值基于列
    primary\u key\u col\u 3
  • 否则,我们使用第一个表中的值
注意:我在实际数据中有更多的“值”列。考虑到下面的玩具示例,我有两个表,
raw\u d
edit\u 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
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;
预期结果如下所示:

    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”,然后使用Pandas在第一个表的查询中“覆盖”行

第一个查询只是从第一个表中获取数据:

SELECT * FROM raw_d
选择“每组最大n”的第二个查询如下:

    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
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;
我计划像中那样合并数据


是否有人知道更好的解决方案,最好只使用SQL?作为参考,我使用PostgreSQL和Pandas作为我的数据堆栈的一部分。

正如我从您的问题中了解到的,有两种方法可以解决此问题

1.使用
完全外部联接

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
select  
distinct on (primary_key_col_1, primary_key_col_2) 
primary_key_col_1, primary_key_col_2, value_col_1, value_col_2 

from (
  select * from edit_d 
  union all
  select primary_key_col_1,primary_key_col_2, null as "primary_key_col_3", 
  value_col_1,value_col_2 from raw_d
  order by primary_key_col_1, primary_key_col_2, primary_key_col_3 desc nulls last
  )tab

2.使用
Union

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
select  
distinct on (primary_key_col_1, primary_key_col_2) 
primary_key_col_1, primary_key_col_2, value_col_1, value_col_2 

from (
  select * from edit_d 
  union all
  select primary_key_col_1,primary_key_col_2, null as "primary_key_col_3", 
  value_col_1,value_col_2 from raw_d
  order by primary_key_col_1, primary_key_col_2, primary_key_col_3 desc nulls last
  )tab

我建议将要求的措辞如下:

  • 从第二个表中选择最近的行
  • 从第一个表中引入不匹配的其他行
这是一个
union all
不同的on

(select distinct on (primary_key_col_1, primary_key_col_2) u.primary_key_col_1, u.primary_key_col_2, u.value_col_1, u.value_col_2
 from updated u
 order by primary_key_col_1, primary_key_col_2, primary_key_col_3 desc
) union all
select r.primary_key_col_1, r.primary_key_col_2, r.value_col_1, r.value_col_2
from raw r
where not exists (select 1
                  from updated u
                  where u.primary_key_col_1 = r.primary_key_col_2 and
                        u.primary_key_col_2 = r.primary_key_col_2
                 );