【问题标题】:How to perform selective SQL insert and update based on whether a row has changed?如何根据行是否更改执行选择性 SQL 插入和更新?
【发布时间】:2020-01-16 04:45:28
【问题描述】:

我想知道根据记录是否已更改将记录从一个表插入到另一个表的最有效方法。除了插入之外,还需要执行更新。

一些重要说明。最新记录的 endDate 为 2100-12-31,表示它是开放式的。 strtDatetheTimestamp 的副本。我正在使用 Snowflake SQL 环境。我无法使用用户定义的函数。


假设我有一个Table1

ID      primKey1  primKey2  checkVar1   checkVar2   theTimestamp   strtDate    endDate
100     1         2         302.1       423.5       2001-07-13     2001-07-13  2100-12-31
101     3         6         506.4       236.7       2005-10-25     2005-10-25  2100-12-31

我想插入 Table2

ID      primKey1  primKey2  checkVar1   checkVar2   theTimestamp
100     1         2         302.1       423.5       2001-10-31
101     3         6         767.9       236.7       2006-12-05  

我要检查记录是否已更改的变量是 checkVar1checkVar2。在这种情况下,ID=100 的记录在插入表(Table2)中没有改变,所以我不想插入这条记录。但是,ID=101 确实发生了变化,所以我想插入这条记录。

Table1 现在应该是这样的:

ID      primKey1  primKey2  checkVar1   checkVar2   theTimestamp   strtDate    endDate
100     1         2         302.1       423.5       2001-07-13     2001-07-13  2100-12-31
101     3         6         506.4       236.7       2005-10-25     2005-10-25  *2006-12-05*
101     3         6         767.9       236.7       2006-12-05     2006-12-05  2100-12-31

如您所见,旧记录的 endDate 已更新为新记录的 theTimestamp。然后插入新记录作为旧记录的延续,采用 2100-12-31 endDate。所以需要同时有一个 UPDATE 和一个 INSERTION。


我的方法:

WITH newTable2Rows AS (
SELECT DISTINCT ID, primKey1, primKey2
FROM Table2
)

WITH maxTable1Rows AS (
SELECT A.ID, A.primKey1, A.primKey2, A.checkVar1, A.checkVar2, A.theTimestamp, A.strtDate, MAX(A.endDate)
FROM Table1 A
JOIN newTable2Rows B
ON A.ID = B.ID, A.primKey1 = B.primKey1, A.primKey2 = B.primKey
GROUP BY A.ID, A.primKey1, A.primKey2, A.checkVar1, A.checkVar2, A.theTimestamp, A.strtDate
)

INSERT INTO Table1 (
ID, primKey1, primKey2, checkVar1, checkVar2, theTimestamp, strtDate, endDate
)
SELECT
ID, primKey1, primKey2, checkVar1, checkVar2, theTimestamp, theTimestamp AS strtDate, '2100-12-31' AS endDate
FROM Table2
MINUS maxTable1Rows

最后有一点点伪代码,因为我还没有完成。但基本上我想从 Table2 中减去最大的 Table1 行,以便从 Table2 中删除重复的行。这将为我留下来自 Table2 的唯一更新行。在此之后,我仍然需要将 Table1 中的最大行数更新为“2100-12-31”。

问题在于将完整行存储到 maxTable1Rows 表中非常昂贵。我正在处理包含 100gb+ 数据的表。我使用的数据集包含超过 2800 万条记录和 200 多列。所以我正在寻找一种可以以最有效的方式执行 UPDATE 和 INSERT 的方法。任何帮助将不胜感激。

【问题讨论】:

  • 我将在表 2 中添加一个新的布尔字段“NewRow”。首先为所有更改的行更新此字段。然后更新 Table1 中的现有行,然后插入新行。最后,将“NewRow”设置为 false,以避免在以后的激活中一遍又一遍地做同样的事情。如果您不能使用某个字段,请创建一个包含所有“NewRow”ID 的临时表。

标签: mysql sql snowflake-cloud-data-platform


【解决方案1】:

这不只是 MERGE 语句的简单用途吗? Snowflake MERGE

MERGE 让您可以完全控制比较列并根据您的条件进行插入或更新。

【讨论】:

  • 我需要同时执行更新和插入操作。我相信合并只能执行一项操作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-07
  • 2013-09-27
  • 2011-07-04
  • 1970-01-01
  • 2011-08-04
  • 1970-01-01
相关资源
最近更新 更多