最小化相同子查询的使用

时间:2018-06-10 16:57:38

标签: sql postgresql

我有以下简化功能:

CREATE OR REPLACE FUNCTION upsert(varchar, varchar, varchar) RETURNS void AS $$
BEGIN

with t1 as (
    select id from table_a where $1 = a_field
), t2 as (
    select id from table_a where $2 = a_field
)
insert into table_b (tba_ref, status)
values
    ((select id from t1), $3),
    ((select id from t2), $3)
on conflict on constraint uniq_constraint do
update set status =
    (CASE
    WHEN table_b.tba_ref = (select id from t1) THEN 'old'
    WHEN table_b.tba_ref = (select id from t2) THEN 'new'
    END)
;
END;
$$ language 'plpgsql';

有什么办法可以摆脱选择的子查询吗?这只是一个简化的示例,它大致反映了原始查询的结构。原始文件中有更多这两个子查询,我希望通过存储结果一次而不是重复运行这些查询来提高性能。

1 个答案:

答案 0 :(得分:0)

我建议将此作为两个单独的更新:

with t1 as (
      select id from table_a where $1 = a_field
    )
insert into table_b (tba_ref, status)
    values ((select id from t1), $3)),
on conflict on constraint uniq_constraint do
    update set status = 'old';

with t2 as (
      select id from table_a where $2 = a_field
    )
insert into table_b (tba_ref, status)
    values ((select id from t2), $3)),
on conflict on constraint uniq_constraint do
    update set status = 'new';

您可以将它们包装在一个交易中。

我认为没有办法通过"另一个"列入on conflict子句。您的insert无法区分这两个值 - 'old''new'未插入表中。