【问题标题】:How to update or insert data with WITH subquery? and avoid `PG::UndefinedTable: ERROR: missing FROM-clause entry for table` error如何使用 WITH 子查询更新或插入数据?并避免`PG::UndefinedTable: ERROR: missing FROM-clause entry for table`错误
【发布时间】:2020-09-27 08:31:18
【问题描述】:

我正在尝试运行简单的 sql 查询:

    <<-SQL.squish
      WITH payloads as (
        INSERT into text_payloads (text, created_at, updated_at)
          SELECT text, created_at, updated_at
          FROM text_messages
        RETURNING id, text, created_at, updated_at
      )
      UPDATE text_messages
      SET
        payload_id = text_payloads.id,
        payload_type = 'TextPayload'
      WHERE
        text_messages.text = text_payloads.text AND
        text_messages.created_at = text_payloads.created_at AND
        text_messages.updated_at = text_payloads.updated_at
    SQL

但出现此错误:

PG::UndefinedTable: ERROR:  missing FROM-clause entry for table "text_payloads"
LINE 1: ...d_type = 'TextPayload' WHERE text_messages.text = text_paylo...
                                                         

我已经尝试添加FROM payloads 甚至LEFT OUTER JOIN text_payloads,但没有任何帮助。如何使用WITH 子查询及其结果实现此更新或类似的插入操作?

非常感谢您!

【问题讨论】:

    标签: sql postgresql pg


    【解决方案1】:

    错误信息很明确:UPDATE 语句中没有 FROM 子句来执行 CTE 之间的连接(我猜你想使用 CTE 而不是 text_payloads) 和 text_messages.
    正确的语法是:

    WITH payloads as (
      INSERT into text_payloads (text, created_at, updated_at)
        SELECT text, created_at, updated_at
        FROM text_messages
      RETURNING id, text, created_at, updated_at
    )
    UPDATE text_messages
    SET
      payload_id = payloads.id,
      payload_type = 'TextPayload'
    FROM payloads  
    WHERE
      text_messages.text = payloads.text AND
      text_messages.created_at = payloads.created_at AND
      text_messages.updated_at = payloads.updated_at 
    

    请参阅demo

    【讨论】:

      【解决方案2】:

      这是工作代码

          <<-SQL.squish
            WITH payloads as (
              INSERT into text_payloads (text, created_at, updated_at)
                SELECT text, created_at, updated_at
                FROM text_messages
              RETURNING id, text, created_at, updated_at
            )
            UPDATE text_messages
            SET
              payload_id = text_payloads.id,
              payload_type = 'TextPayload'
            FROM payloads, text_payloads
            WHERE
              text_messages.text = text_payloads.text AND
              text_messages.created_at = text_payloads.created_at AND
              text_messages.updated_at = text_payloads.updated_at
          SQL
      

      【讨论】:

        猜你喜欢
        • 2012-03-13
        • 2015-02-16
        • 1970-01-01
        • 2015-10-30
        • 1970-01-01
        • 2015-01-22
        • 2019-02-17
        • 2016-03-24
        • 1970-01-01
        相关资源
        最近更新 更多