PostgreSQL15带来了一个名为MERGE的新SQL命令。MERGE已经在SQL标准中使用了很长一段时间,但它只是进入了PostgreSQL代码库。在MERGE之前,如果您想从源表刷新目标表,在Postgres15之前,您可以将"upsert"方法与On CONFLICTclause一起使用。
现在,可以使用MERGE代替!合并很有意义的一些情况是:
通过外部数据包装器从外部源加载数据
分阶段和批处理过程作业
关于MERGE
让我们看看文档中的概要:

我们可以读到data_source的源可以是一个表,也可以是由于使用with_query之前带到命令中的一些数据,或者在使用source_query之后的合并中。当数据匹配时,即target_table_name中有一条匹配的记录,我们可以指定要做什么:
执行merge_update中定义执行update(请参阅更新集部分或
按照merge_delete执行delete或
什么都不做
当数据不匹配时,即target_table_name中没有匹配的记录,然后我们进行插入(参见merge_update)。
MERGE 示例-远程传感器和批次
在与客户合作时,我看到需要使用远程传感器或工作站加载数据。 任何"定期发送数据"并将该数据加载到数据集中的东西都是常见的需求。我对使用MERGE为Postgres用户解决这些问题感到特别兴奋。
为了解释MERGE的这个数据加载用例,我将设置一个例子。我们将有一个站的数据库,这是一个远程测量工具,数据间歇性地进入。
流数据,数据连续到达
站发出周期性和间歇性的数据测量
有一批收集这些数据
station_data_new是通用存储的临时表
数据存储长期station_data_actual与最后可能的值
我们想跟踪电台的创建时间
让我们为测试目的创建一些表。 请注意,临时表station_data_new仅存在于给定会话的上下文中。

让我们在station_data_new中创建一些示例数据:我们的第1个5站已经启动并发送了第1批数据:

基本MERGE
此时,我们可以使用SELECT from station_data_new到station_data_actual进行简单的insert。 相反,我们将使用MERGE,因为我们计划在数据已经存在的情况下,将发布update而不是insert。
如果执行一次,则返回MERGE5,并且数据插入到station_data_actual中,其中created和update中的时间戳具有相同的值。
要做更多的测试,你可以:
截断表station_data_new;
通过使用generate_series(1,10)
更改generate_series(1,5),在其中重新创建数据
再次发出与我们之前运行的相同的合并
您将看到station_data_actual中的数据已更新。站1至5将具有更新的状态,站6至10将被created和updated。
结论
MERGE是PostgreSQL粉丝期待已久的功能!现在我们有了。我鼓励您在合并数据库中的现有数据时查看流程。在此示例中,使用现有数据输入的新数据可能是使用此功能的好地方。
MERGE打开了聚合和/或合并来自许多数据库的数据的新用法。 在分布式模型中,所有数据都存在于不同的位置,使用外部数据包装器合并可能是一个非常优雅的解决方案。MERGE可以简化数据库生命周期中对数据的处理。 具有强大和快速的SQL语句,而不是函数或其他复杂的操作。





