【问题标题】:How do several INSERT and SELECT statements work in a common table expression?多个 INSERT 和 SELECT 语句如何在公用表表达式中工作?
【发布时间】:2019-12-10 08:50:20
【问题描述】:

我正在尝试通过 arelle 将 xbrl 文件导入 Postgres。它生成以下sql:

WITH row_values (report_id, document_id, xml_id, xml_child_seq, source_line, parent_datapoint_id, aspect_id, context_xml_id, entity_identifier_id, period_id, aspect_value_selection_id, unit_id, is_nil, precision_value, decimals_value, effective_value, value) AS 
(
  VALUES (3150993::bigint, 3150994::bigint, NULL, '/1/5', 36::integer, NULL::bigint, 22904::bigint, 'c-01', 3151029::bigint, 3151079::bigint, 3162474::bigint, 3150995::bigint, FALSE::boolean, NULL, '0', 1580::double precision, '1580'),
         (3150993, 3150994, NULL, '/1/6', 37, NULL, 22979, 'c-01', 3151029, 3151079, 3162474, NULL, FALSE, NULL, NULL, NULL, '011X0082'),
  -- more values here
         (3150993, 3150994, NULL, '/1/7700166', 12475343, NULL, 22625, 'c-387173', 3151076, 3151079, 3254880, NULL, FALSE, NULL, NULL, NULL, '2017-05-01')
), insertions AS (
   INSERT INTO data_point (report_id, document_id, xml_id, xml_child_seq, source_line, parent_datapoint_id, aspect_id, context_xml_id, entity_identifier_id, period_id, aspect_value_selection_id, unit_id, is_nil, precision_value, decimals_value, effective_value, value)
   SELECT report_id, document_id, xml_id, xml_child_seq, source_line, parent_datapoint_id, aspect_id, context_xml_id, entity_identifier_id, period_id, aspect_value_selection_id, unit_id, is_nil, precision_value, decimals_value, effective_value, value
  FROM row_values v
  RETURNING datapoint_id, document_id, xml_child_seq
)
SELECT datapoint_id, document_id, xml_child_seq
FROM insertions;

withinsert into 和多个 select 语句如何存在于一条指令中(没有一个 ;)?

【问题讨论】:

  • 投反对票时添加评论。我根本不是 postgres 专家。
  • 我建议查看 PostgreSQL documentation for the WITH statement。我链接到最新版本。请在阅读文档后完善您的问题。使 sn-p 更具可读性也将帮助人们回答您的问题。干杯!

标签: sql postgresql common-table-expression


【解决方案1】:

这是一个数据modifying CTE

但是,它的结构方式太复杂了。

整个语句可以简化为:

INSERT INTO data_point (....)
VALUES (...),
       (...),
        ...
       (...)
returning datapoint_id, document_id, xml_child_seq;

第一个 CTE 仅定义要​​插入的行。在 CTE 之外,您也可以这样做:

select *
from ( values (1,2), (2,3)) as dummy(x,y);

第一个 CTE 的值随后被第二个 CTE 用作insert ... select 语句的源。它使用returning 子句,以便INSERT 生成一组行,然后使用最终的SELECT 语句来显示它们。


如果目标是将值和 INSERT 分开,那么这也可以在 CTE 的最终 SELECT 语句中完成:

类似这样的:

WITH row_values as (...) 
(
  VALUES (...),
         (...),
          ...
         (...)
) 
INSERT INTO data_point (....)
SELECT ...
FROM row_values
returning datapoint_id, document_id, xml_child_seq;

在我看来仍然是不必要的复杂(与简单的insert .. values .. 版本相比)。


至于为什么Arelle 造成了我不能说的这么一团糟。

【讨论】:

    猜你喜欢
    • 2020-10-08
    • 2010-10-09
    • 1970-01-01
    • 1970-01-01
    • 2019-12-20
    • 2021-06-16
    • 2016-06-14
    • 2021-05-15
    • 1970-01-01
    相关资源
    最近更新 更多