0

我正在创建几个表并将它们中的数据合并到一个表中。这些表具有相似的 col1 和 col2 列,但这些列中的值可以不同,例如。tab1 的第 1 行上的 col1 可能有“0”,而 tab2 中的 col1 可能在 col1“1”的同一行上。只有在这种情况下,我才需要更新第 1 行 col1 中 tab1 的值。请看以下示例:

BEFORE MERGING               
tab1:
id col1 col2
1  0    0
2  0    1
3  0    0
                              AFTER MERGING WITH tab2
tab2:                         tab1:
id col1 col2                   id col1 col2
1  1    0           --->       1  1    0
2  0    0                      2  0    1
3  0    0                      3  0    0

为此,我使用以下查询:

merge into tab1 st
   using (select id, col1, col2 from tab2) ss
   ON (st.id=ss.id)
    when matched then 
    update set  st.col1 = ss.col1,
                st.col2 = ss.col2 

  where ss.col1 != 0 or ss.col2 != 0
  when not matched then
    insert (st.id, st.col1, st.col2)
    values (ss.id, ss.col1, ss.col2)
    ; 

我只是在学习 sql,所以直到现在我才注意到这个查询不正确。它可以用来自tab2的“0”覆盖tab1中的“1”值。请帮我改进这个查询,我卡住了。

4

2 回答 2

1

您应该使用 的最大值进行更新{ss.coln, st.coln}。例如,使用GREATEST

MERGE INTO tab1 st
USING (SELECT id, col1, col2 FROM tab2) ss
ON (st.id = ss.id)
WHEN MATCHED THEN
   UPDATE
      SET st.col1 = greatest(ss.col1, st.col1), 
          st.col2 = greatest(ss.col2, st.col2)
    WHERE ss.col1 > st.col1
       OR ss.col2 > st.col2
WHEN NOT MATCHED THEN
   INSERT (st.id, st.col1, st.col2) 
   VALUES (ss.id, ss.col1, ss.col2);
于 2013-03-26T15:54:07.117 回答
1

您可以在设置值时使用 CASE 表达式来控制分配的值。尝试类似:

merge into tab1 st
   using (select id, col1, col2 from tab2) ss
   ON (st.id=ss.id)
    when matched then 
    update set  st.col1 = CASE WHEN st.col1 = 0 THEN ss.col1 ELSE st.col1 END,
                st.col2 = CASE WHEN st.col2 = 0 THEN ss.col2 ELSE st.col2 END

  where ss.col1 != 0 or ss.col2 != 0
  when not matched then
    insert (st.id, st.col1, st.col2)
    values (ss.id, ss.col1, ss.col2)
    ; 

因此,在 WHEN MATCHED 情况下,如果 tab1 (st) 的值为零,则将其更改为 tab2 (ss) 的值,否则只需将 tabl1 的值设置为自身。

分享和享受。

于 2013-03-26T15:50:37.707 回答