仅插入唯一行并更新已存在的行

Posted

技术标签:

【中文标题】仅插入唯一行并更新已存在的行【英文标题】:Insert unique rows only and update rows that already exist 【发布时间】:2020-02-07 23:07:19 【问题描述】:

我有一个名为“Day Zero”的表,其中包含一个 Listing_id 列、地址列和状态列。 Listing_id 始终是唯一的,并且是 int 数据类型。每行的状态列都是Existing

每天我会得到两个文本文件,一个叫Listings,另一个叫Sold,我使用BULK insert直接将数据导入到表中,数据就是这两个文本文件只包含一个listing_id和address列.

我想弄清楚的是如何使用以下逻辑将这些文件中的数据导入表中:

    如果listing_id 存在于day zero 文件和listings 文件中,则不要导入新行并将现有行上的status 更改为'updated'

    如果listing_id 不存在于day zero 文件中并且存在于listing_file 中,则插入新行并将status 更改为'new'

    如果列表 id 存在于 day zero 文件中并且存在于 sold_file 中,则不要导入新行并将现有行上的 status 更改为 'sold'

    如果listing_id 不存在于day zero 文件中并且存在于sold_file 中,则插入新行并将status 更改为'unknown_sale_event'

【问题讨论】:

【参考方案1】:

您可以将每个文件加载到单独的临时表中,然后使用SQL Server's merge syntax 实现逻辑:

以下查询合并来自 LISTINGS 文件的数据(假设该文件已加载到临时表 #listings 中):

merge day_zero d 
using #listings l on (l.listing_id = d.listing_id)
when matched
    then update set d.status = 'UPDATED'
when not matched by target
    then insert(listing_id, address, status) 
    values(l.listing_id, address, 'NEW')

这是对 SALES 文件的等效查询:

merge day_zero d 
using #sold s on (s.listing_id = d.listing_id)
when matched
    then update set d.status = 'SOLD'
when not matched by target
    then insert(listing_id, address, status) 
    values(s.listing_id, address, 'UNKNOWN_SALE_EVENT')

【讨论】:

以上是关于仅插入唯一行并更新已存在的行的主要内容,如果未能解决你的问题,请参考以下文章

如果唯一密钥已存在,则插入或更新

如何检查数据库中是否已存在一组行并跳过迁移?

如果唯一键已存在,则插入或更新记录

插入 MySQL 表或更新(如果存在)

插入 MySQL 表或更新(如果存在)

postgres:更新冲突插入行并返回旧值