在SQL中混淆“不匹配时”(如何正确合并)

时间:2013-03-26 15:28:28

标签: sql database oracle merge

我正在创建几个表并将它们中的数据合并为一个表。这些表具有类似的列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所以只是现在我注意到这个查询不正确。它可以覆盖tab1中的“1”值,其中“0”来自tab2。请帮我改进这个问题,我被困住了。

2 个答案:

答案 0 :(得分: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中的值设置为自身。

分享并享受。

答案 1 :(得分: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);