【问题标题】:writeable common table expression and multiple insert statements可写公用表表达式和多个插入语句
【发布时间】:2016-10-18 11:49:30
【问题描述】:

如何在有效的 Postgres SQL 查询中编写以下内容:

with foo as (select * from ...)
insert into bar select * from foo
insert into baz select * from foo

【问题讨论】:

    标签: sql postgresql common-table-expression


    【解决方案1】:

    您可以使用 CTE,如果您想在一个语句中完成所有操作:

    with foo as (
          select * from ...
         ),
         b as (
          insert into bar
              select * from foo
              returning *
         )
    insert into baz
        select * from foo;
    

    注意事项:

    • 您应该使用insert 包含列列表。
    • 您应该明确select * 指定列名。这很重要,因为两个表中的列可能不匹配。
    • 我总是在 CTE 中使用 returningupdate/insert/delete。这是正常的用例 - 例如,您可以从插入中获取序列号。

    【讨论】:

    • 这给了我以下错误:错误:“(”第 73 行或附近的语法错误:b as (^ SQL 状态:42601 字符:1778 @Gordon Linoff
    • @Sam 。 . .此答案中没有第 73 行。如果您有问题,请提出问题。
    • 是的,对不起,我试图在我的代码中实现这个逻辑,结果我使用了 'foo' 的别名,这给了我一个错误,'b as (' 但是当我删除别名时,成功了!@Gordon Linoff
    【解决方案2】:

    with 子句的范围只是一个查询。我能想到的唯一解决方案是创建一个视图并在插入完成后将其删除。它不会像 CTE 那样完全短暂,但这里没有数据重复 - 只是一个(相对)便宜的 DDL 操作:

    -- Create the view
    CREATE VIEW foo AS SELECT * FROM ...;
    
    -- Perform the inserts
    INSERT INTO bar SELECT * FROM foo;
    INSERT INTO baz SELECT * FROM foo;
    
    -- Drop the view when you're done
    DROP VIEW foo;
    

    【讨论】:

    • 可以用一个 CTE 做到这一点,不需要(临时)视图。
    猜你喜欢
    • 2020-10-08
    • 1970-01-01
    • 1970-01-01
    • 2010-10-09
    • 1970-01-01
    • 2011-08-04
    • 2015-08-31
    • 1970-01-01
    相关资源
    最近更新 更多