几个INSERT和SELECT语句如何在公用表表达式中工作?

时间:2019-12-10 08:50:20

标签: sql postgresql common-table-expression

我正在尝试通过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语句如何在一条指令中存在(没有一个;)?

1 个答案:

答案 0 :(得分:0)

这是数据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造成了我无法说的一团糟。