如何从包含要更新的基表中的数据的连接表中获取数据?

Posted

技术标签:

【中文标题】如何从包含要更新的基表中的数据的连接表中获取数据?【英文标题】:How to get data from a joined table which contains data from the base table that is going to be updated? 【发布时间】:2019-07-02 18:38:58 【问题描述】:

我有以下代码,它使用连接 HOTLINKS 的信息更新基表 ORDERS_REPORT_BASE。更新必须发生在

1) HOTLINKS 中的 SCAC 匹配 ORDERS_REPORT_BASE 中的任何 STD_CARR_CD 列(STD_CARR_CD 或 STD_CARR_CD_EV_CDC 或 STD_CARR_CD_CUS 或 STD_CARR_CD_EV_CUS)

--> 1a 如果 STD_CARR_CD_EV_CUS 有一个值,那么它会忽略所有其他值并使用它。如果 STD_CARR_CD_CUS 有值并且 EV_CUS 为 NULL,那么它会使用它......等等

2) 根据情况,CARR_TRACKING_NUM 或 ACTUAL_TRACKING_NUM 不为空

似乎 2) 根据结果工作,但是,1) 在通过每个 CASE 时失败,当它找到 STD_CARR_CD 时,如果不匹配,则不会进入后续场景。

这是有效的代码,但它没有考虑 SCAC 以前是否存在

UPDATE GDTS.ORDERS_REPORT_BASE BASE SET BASE.HOTLINK = 
CASE WHEN BASE.CARR_TRACKING_NUM_CDC IS NULL AND BASE.ACTUAL_TRACKING_NUM IS NULL THEN NULL 
WHEN BASE.CARR_TRACKING_NUM_CDC IS NOT NULL AND BASE.ACTUAL_TRACKING_NUM IS NULL THEN TRIM(HOT.URL1) || TRIM(BASE.CARR_TRACKING_NUM_CDC) || TRIM(HOT.URL2) 
ELSE TRIM(HOT.URL1) || TRIM(BASE.ACTUAL_TRACKING_NUM) || TRIM(HOT.URL2) END
FROM (SELECT DISTINCT SCAC, URL1, URL2 FROM GDTS.HOTLINKS) HOT WHERE 
(TRIM(HOT.SCAC) = CASE WHEN BASE.STD_CARR_CD_EV_CUS IS NOT NULL
THEN BASE.STD_CARR_CD_EV_CUS
WHEN BASE.STD_CARR_CD_CUS IS NOT NULL AND BASE.STD_CARR_CD_EV_CUS IS NULL 
THEN BASE.STD_CARR_CD_CUS
WHEN BASE.STD_CARR_CD_EV_CDC IS NOT NULL AND BASE.STD_CARR_CD_CUS IS NOT NULL AND BASE.STD_CARR_CD_EV_CUS IS NULL
WHEN BASE.STD_CARR_CD IS NOT NULL AND BASE.STD_CARR_CD_EV_CDC IS NULL AND BASE.STD_CARR_CD_CUS IS NULL AND BASE.STD_CARR_CD_EV_CUS IS NULL
THEN BASE.STD_CARR_CD END)

在这种情况下,HOTLINK 字段不会更新,因为 STD_CARR_CD_CUS 不是空白,但匹配不会产生任何结果('MARUUN' 不是 HOTLINK 表中的 SCAC)

它应该最终与不为空的 STD_CARR_CD 匹配(UPS 值)

我尝试在每个 HOT.SCAC equals 处添加一个 EXISTS 子句,因此它还会检查是否在表中找到了 SCAC

...
FROM (SELECT DISTINCT SCAC, URL1, URL2 FROM GDTS.HOTLINKS) HOT WHERE 
(TRIM(HOT.SCAC) = CASE WHEN BASE.STD_CARR_CD_EV_CUS IS NOT NULL AND EXISTS (SELECT DISTINCT SCAC FROM GDTS.HOTLINKS WHERE TRIM(HOT.SCAC) = BASE.STD_CARR_CD_EV_CUS)
THEN BASE.STD_CARR_CD_EV_CUS
...

但是,这个添加最终导致了重复错误。似乎从 BASE 表中检索了几行以更新整个结果。

错误:[IBM][CLI Driver][DB2/LINUXX8664] SQL0788N 语句未处理 因为目标表 \"GDTS.ORDERS_REPORT_BASE\" 的一行是 多次识别更新、删除或插入。 SQLSTATE=21506

ORDERS_REPORT_BASE 中的键是 PO_ID,但为了与 HOTLINKS 表匹配,我需要使用 STD_CARR_CD 与 SCAC 中的任何一个

我需要检查任何 STD_CARR_CD 是否存在于 HOTLINKS 表中,以便 CASE 考虑它来创建匹配逻辑。如果它不存在(如图像示例),它应该转到另一个 CASE 语句。

谢谢

【问题讨论】:

【参考方案1】:

您可以使用合并来更新或插入或删除。也许您可以尝试这样做以实现您想要做的事情。

MERGE INTO target_table AS target
USING (

VALUES (1, 2, 3),
       (4, 5, 6),
       (7, 8, 9)
        -- more rows
        -- Or even you can use a complex join that gives the data set you want to alter
    ) AS source (C1, C2, C3)
    ON target.key_to_match = source.key_to_match
    WHEN MATCHED AND tab.C1 != source.C1 -- or any other condition if needed
    THEN UPDATE SET target.C1 = source.C1,
                   target.C2 = source.C2,
                   target.C3 = source.C3
    WHEN NOT MATCHED THEN
        INSERT (C1, C2, C3)
        VALUES (source.C1, source.C2, source.C3)

【讨论】:

您好,感谢您的回答。我担心的是,使用 MERGE 只允许我定义 1 个 ON 子句,而我的目标是定义 4 个可能的场景。如果目标表中的键与源表中的键不匹配,那么我应该在目标表中查找另一列,看看是否可以匹配。 可以在merge里面使用case语句。例如:MERGE into TARGET_table T USING (SELECT CASE WHEN ... THEN ... WHEN ... THEN END AS col1 FROM table1 t1 JOIN table2 t2 ON t1.keycol1=t2.keycol2) S ON T.key_to_match = S.key_to_match;【参考方案2】:

我设法使用

检查每个 CASE 语句中是否存在 SCAC
...
TRIM(HOT.SCAC) IN (SELECT SCAC FROM GDTS.HOTLINKS)
...

谢谢!

【讨论】:

以上是关于如何从包含要更新的基表中的数据的连接表中获取数据?的主要内容,如果未能解决你的问题,请参考以下文章

ORACLE 中视图更新可以更新基表中数据,视图更新应该满足啥条件?

视图基表中的 SQL 更新行

如何更新主表当前行的输入类型文本中的值从模态窗口表中获取值

如何从 MYSQL 中的数据透视表中获取最后更新的价格

如何从更新表中获取最新状态并将其与 MySQL 中的详细信息表连接?

插入(或更新)到基表后视图是不是立即更新