一个 INSERT 与多个 SELECT

One INSERT with multiple SELECT

我已经读过 this, and this,但我无法使这个 SQL 起作用:

INSERT INTO main_phrase (description) VALUES ('Mot commun féminin pluriel animaux');
/* ERROR: */
WITH
  t1 AS (
    SELECT id 
    FROM main_phrase 
    WHERE description='Mot commun féminin pluriel animaux'
  ),
  t2 AS (
    SELECT id 
    FROM main_groupecategories 
    WHERE description='Mot commun féminin pluriel animaux'
  )
INSERT 
  INTO main_phrasegroupecategories (phrase_id, groupe_categories_id)
  VALUES                           (t1.id,     t2.id);

我得到:

ERROR: missing entry for the clause FROM for table t1

我错过了什么?

试试这个:

INSERT INTO main_phrase (phrase_id, groupe_categories_id) 
WITH
  t1 AS (
    SELECT id 
    FROM main_phrase 
    WHERE description='Mot commun féminin pluriel animaux'
  ),
  t2 AS (
    SELECT id 
    FROM main_groupecategories 
    WHERE description='Mot commun féminin pluriel animaux'
  )
  select t1.id, t2.id
  from t1,t2;

假设

  • 您想 link 将 main_phrase 中新插入的行添加到 main_groupecategories 中具有相同 description 的行。
  • main_phrase.idserial 列。

错误解释

您不能在 free-standing VALUES 表达式中引用任何表(包括 CTE),您必须使用带有 FROM 子句的 SELECT。但是有一个更好的解决方案。见下文。

更好的查询

改用 data-modifying CTE 可以使整个操作更短、更安全、更快:

WITH p AS (
   INSERT INTO main_phrase (description)
   VALUES ('Mot commun féminin pluriel animaux')  -- provide description once
   RETURNING id, description  -- and reuse it further down
   )
INSERT INTO main_phrasegroupecategories (phrase_id, groupe_categories_id)
SELECT p.id, g.id
FROM   p
JOIN   main_groupecategories g USING (description);

如果您想使用新行的任何值,请立即将它们与另一个 RETURNING 子句一起返回到第二个 INSERT.

为什么在您的(假定的)many-to-many relationship 的两个表中冗余地具有相同的 description?可能是你的数据库设计有问题。

相关:

  • PostgreSQL multi INSERT...RETURNING with multiple columns
  • SELECT * FROM NEW TABLE equivalent in Postgres