【问题标题】:Is it possible to reuse scalar result from a single subquery in insert query in Postgres?是否可以在 Postgres 的插入查询中重用单个子查询的标量结果?
【发布时间】:2020-06-06 13:08:41
【问题描述】:

我想在同一个查询中在 Postgres DB 表中插入几行数据,但是需要使用子查询的标量结果和传递的绑定参数来计算其中一列的值。计算是两个 Postgres 数组的串联。

我可以通过这样的查询来做到这一点:

INSERT INTO my_table (col1, col2, computed_col)
VALUES 
  (
    :col1Val1,
    :col2val1,
    (SELECT some_col FROM some_table WHERE id = :id) || ARRAY[:computed_col1]::bigint[]
  ),
  (
    :col1Val2,
    :col2val2,
    (SELECT some_col FROM some_table WHERE id = :id) || ARRAY[:computed_col2]::bigint[]
  );

CTE 也可以,但它看起来没有必要,因为我们仍然需要从 CTE“表”中为每组值进行 SELECT 子查询。

如您所见,SELECT 子查询对于要插入的每组数据都是相同的。那么是否有可能以某种方式指定单个子查询并重用结果而不重复 SELECT 子查询,或者是否有其他方法可以优化上述查询?

从性能的角度来看,查询会导致哪些问题?

【问题讨论】:

    标签: sql database postgresql insert sql-insert


    【解决方案1】:

    您可以使用insert . . . select,基本上将VALUES() 移动到FROM 子句中:

    INSERT INTO my_table (col1, col2, computed_col)
        SELECT v.col1, v.col2, x.some_col  || v.computed
        FROM (SELECT some_col FROM some_table WHERE id = :id
             ) x CROSS JOIN
             (VALUES (:col1Val1, :col2val1, ARRAY[:computed_col1]::bigint[]),
                     (:col1Val2, :col2val2, ARRAY[:computed_col2]::bigint[])
             ) v(col1, col2, computed);
    

    【讨论】:

    • 感谢您的回答,您认为哪种查询会更高效(当然,如果没有解释/分析工具是可能的)?
    • @dajnz 。 . .性能应该与添加两行无关。如果some_tableid 上有一个索引(可能是主键),那么如果你能衡量性能差异,我会感到惊讶。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    • 2023-02-04
    • 1970-01-01
    • 2021-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多