是否可以在ON CONFLICT DO UPDATE中使用两个where子句?

时间:2018-08-23 07:34:35

标签: postgresql upsert

我正在尝试使用ON CONFLICT DO UPDATE中的两个不同的where子句设置两列,例如:

INSERT INTO table AS t (id, detail, areaid)
ON CONFLICT (id) DO UPDATE
SET detail = EXCLUDED.detail
WHERE (t.detail IS NULL AND EXCLUDED.detail IS NOT NULL),
areaid = EXCLUDED.areaid
WHERE (t.areaid IS NULL AND EXCLUDED.areaid IS NOT NULL);

这将导致语法错误。可以这样做吗?

2 个答案:

答案 0 :(得分:0)

您不能这样做,但是您可以这样做:

INSERT INTO "table" AS t (id, detail, areaid)
VALUES (...) | SELECT ...
ON CONFLICT (id) DO UPDATE
SET detail = CASE WHEN t.detail IS NULL
                     AND EXCLUDED.detail IS NOT NULL
                  THEN EXCLUDED.detail
                  ELSE t.detail
             END,
    areaid = CASE WHEN t.areaid IS NULL
                     AND EXCLUDED.areaid IS NOT NULL
                  THEN EXCLUDED.areaid
                  ELSE t.areaid
             END;

缺点是detailareaid始终会更新,即使该值没有更改,也会为自动真空带来更多工作。

答案 1 :(得分:0)

我认为您可以尝试这样的事情:

INSERT INTO table AS t (id, detail, areaid)
ON CONFLICT (id) DO UPDATE
SET detail = CASE WHEN (t.detail IS NULL AND EXCLUDED.detail IS NOT NULL) 
                  THEN EXCLUDED.detail 
                        else 
                   detail end 
    ,
               areaid = CASE WHEN (t.areaid IS NULL AND EXCLUDED.areaid IS NOT NULL)
                              THEN EXCLUDED.areaid
                              else areaid 
                         end