【问题标题】:Upsert query on postgres SQL while checking if need to keep old values or insert new values?在检查是否需要保留旧值或插入新值时在 postgres SQL 上进行 Upsert 查询?
【发布时间】:2020-09-05 06:48:15
【问题描述】:

我有一个 postgres SQL 查询,我想在其中执行 upsert。 我的 pk1, pk2 列是复合主键。如果与主键约束冲突,我想更新 3 列 dk1, dk2, timek。 此外,当我更新冲突列时,比如timek 列,那么我需要检查新值是否小于旧值,并相应地选择是否需要使用旧值或新值。 这是我的查询,但它会引发错误。 我是 postgres SQL 的新手,请提出问题?

INSERT INTO data_reports (pk1, pk2, dk1, dk2, dk3, timek, valuek)  VALUES (?, ?, ?, ?, ?, ?, ?)  
ON CONFLICT (pk1, pk2) DO UPDATE SET 
dk1 = EXCLUDED.dk1, 
dk2 = CASE WHEN (dk2 < EXCLUDED.dk2) THEN EXCLUDED.dk2 ELSE dk2 END), // I believe dk2 (existing value in DB) is not selected but how to do that
timek = CASE WHEN (timek < EXCLUDED.timek) THEN EXCLUDED.timek ELSE timek END);

【问题讨论】:

    标签: sql database postgresql upsert


    【解决方案1】:
    1. 您可以通过指定表名来引用更新前的列值:例如data_reports.dk2
    2. 开闭括号,有5个(s和7个)s。
    3. -- 开始评论,或以/**/ 附上评论。
    INSERT INTO data_reports (pk1,pk2,dk1,dk2,dk3,timek,valuek)
    VALUES (1,1,9,9,9,9,9)
    ON CONFLICT (pk1,pk2) DO
    UPDATE
    SET
        dk1 = EXCLUDED.dk1,
        dk2 =
        (CASE
            WHEN (data_reports.dk2 < EXCLUDED.dk2) THEN EXCLUDED.dk2
            ELSE data_reports.dk2
        END),
        timek =
        (CASE
            WHEN (data_reports.timek < EXCLUDED.timek) THEN EXCLUDED.timek
            ELSE data_reports.timek
        END);
    

    【讨论】:

    • 感谢@shoek,正在寻找要访问的更新前列值。它有效!
    【解决方案2】:

    仅供参考:您可以通过用 LEAST 函数替换 CASE 表达式来简化:

    insert into data_reports (pk1,pk2,dk1,dk2,dk3,timek,valuek)
    values (1,1,9,9,9,9,9)
    on conflict (pk1,pk2) do
    update
    set
        dk1 = excluded.dk1,
        dk2 = least(data_reports.dk2, excluded.dk2),
        timek = least(data_reports.timek, excluded.timek); 
    

    【讨论】:

    • 谢谢! @Belayer这确实是更好的答案,但根据我想使用CASE ELSE THEN的问题。 :)
    猜你喜欢
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 2015-03-07
    相关资源
    最近更新 更多