SQL:如果存在则更新,否则插入...但对于具有不同值的多行
Posted
技术标签:
【中文标题】SQL:如果存在则更新,否则插入...但对于具有不同值的多行【英文标题】:SQL: update if exists, else insert... but for multiple rows with different values 【发布时间】: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。至少据我所知...请纠正我!
【问题讨论】:
【参考方案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
【讨论】:
以上是关于SQL:如果存在则更新,否则插入...但对于具有不同值的多行的主要内容,如果未能解决你的问题,请参考以下文章