【问题标题】:SQL: update if exists, else insert... but for multiple rows with different valuesSQL:如果存在则更新,否则插入...但对于具有不同值的多行
【发布时间】:2011-03-18 17:59:32
【问题描述】:

我想将插入/更新与 case 语句结合起来,这意味着如果它不存在我想插入该行,如果它存在则更新它,但在这两种情况下使用不同的值(更新时取决于 id ) 并在插入时,然后我设置它...

这应该发生在单个 SQL 语句中:-)

简而言之:我正在尝试将这两个语句合并为一个语句:

1)。插入/更新:

MERGE INTO table_name USING dual ON (id='{id}')
WHEN MATCHED     THEN UPDATE SET {col1}='{val1}', {col2}={val2}
WHEN NOT MATCHED THEN INSERT ({id}, {col1}, {col2}) VALUES ('{id}', '{val1}', {val2})

2)。用大小写更新不同的值:

UPDATE SIGNALVALUE
    SET
        SIGNUMVALUE = CASE SIGID
        WHEN 49634 THEN 1.1
        WHEN 49674 THEN 2.2
        WHEN 49675 THEN 1.8
        END,
        UPDATETIME = CASE SIGID
        WHEN 49634 THEN TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR')
        WHEN 49674 THEN TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR')
        WHEN 49675 THEN TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR')
        END
   WHERE SIGID IN (49634, 49674, 49675)

这些陈述只是示例。实际上,要插入/更新的行更多,而且这种情况经常发生,所以我试图尽量减少查询量。

我也不能进行更新,然后查看有多少行受到影响,然后插入没有影响的行,因为我不知道需要插入的行的 ID 与需要更新的行的 ID。至少据我所知...请纠正我!

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    不必是using子句中的表,也可以使用SQL查询。
    至少那是我认为你所追求的:)

    merge 
     into target_table
    using (select case when ... then ... else ... end as id
             from dual
          ) source_table
        on(target_table.id = source_table.id)
    when matched then
       update 
          set ...
    when not matched then
       insert (...)
       values (...)
    

    如果有帮助,请告诉我。如果是这样,我可能也可以帮助编写最终查询。

    【讨论】:

    • 嘿。是的,听起来不错。其实我刚才也在玩dual。虽然有点不同:[编辑:cmets 中的 ok 代码不好]。不管怎样,你所做的看起来很有希望 :-) 但我不确定如何选择使用案例,我现在正在研究它,但如果你有任何提示,那就太好了!
    • 好的,我让它工作了。谢谢!你的回答结合我玩的对偶=成功! :-) 下面是我的查询。如果您能看一下并告诉我可以改进的地方,我将不胜感激!
    • @o1iver,如果您使用一些示例数据和预期结果更新您的问题,我可以为您提供帮助。
    • @o1iver,啊,没有看到最后一条评论 :) 很高兴我能提供帮助。如果您发现它有帮助,请不要忘记接受答案:)
    【解决方案2】:
    MERGE INTO SIGNALVALUE USING (
    SELECT 49674 as SIGID,
            TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR') AS UPDATETIME,
            '777' as SIGNUMVALUE
            FROM dual
            UNION ALL
    SELECT 49675 as SIGID,
            TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR') AS UPDATETIME,
            '777' as SIGNUMVALUE
            FROM dual
            UNION ALL
    SELECT 49676 as SIGID,
            TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR') AS UPDATETIME,
            '777' as SIGNUMVALUE
            FROM dual
    ) n
    ON(SIGNALVALUE.SIGID = n.SIGID)
    WHEN NOT MATCHED THEN
        INSERT (SIGID, SIGNUMVALUE, UPDATETIME) VALUES (n.SIGID, n.SIGNUMVALUE, n.UPDATETIME)
    WHEN MATCHED THEN
        UPDATE SET SIGNUMVALUE=n.SIGNUMVALUE, UPDATETIME=n.UPDATETIME
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-23
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-17
      • 2015-08-14
      相关资源
      最近更新 更多