“计划不应该引用子计划的变量”错误

时间:2013-11-01 01:34:40

标签: sql postgresql

我需要使用另一个表中的值

更新表中的2列
UPDATE transakcje t SET s_dzien = s_dzien0, s_cena = s_cena0
    FROM
        (SELECT c.price AS s_cena0, c.dzien AS s_dzien0 FROM ciagle c 
            WHERE c.dzien = t.k_dzien ORDER BY s_cena0 DESC LIMIT 1) AS zza;

但我收到了一个错误:

  

计划不应该参考子计划的变量。

数据库结构尽可能简单:transakcjek_dzienk_cenas_dziens_cenaciagle有字段{{ 1}},price

我正在运行PostgreSQL 9.3。

修改

我想更新dzien的所有记录。 对于每一行,我必须找到transakcje中有一行ciagledzien price,并将此pricedzien保存到transakcje。< / p>

ciagle中,有许多行具有相同的dzien(列不明显)。

1 个答案:

答案 0 :(得分:3)

问题

您拥有的表格:

UPDATE tbl t
SET    ...
FROM (SELECT ... WHERE col = t.col LIMIT 1) sub

......开始时是非法的。正如错误消息所示,子查询无法引用UPDATE子句中的表。 FROM列表中的项目通常无法引用同一级别的其他项目(LATERAL in Postgres 9.3 or later除外)。 UPDATE子句中的子查询永远不能引用FROM子句中的表(并且在Postgres 9.3中没有更改)。

即使有可能,结果仍然是无稽之谈有两个原因:

  • 带有LIMIT 1的子查询产生完全一个行(总计),而您显然希望每dzien个特定值:

      

    来自ciagle的一行与dzien相同

  • 一旦你修改它并计算每dzien一个价格,你最终会得到类似交叉连接的东西,除非你添加WHERE条件以明确地将子查询的结果加入到要更新的表。引用the manual on UPDATE

      

    换句话说,目标行不应该连接到多行   其他表格。如果是,则只有一个连接行   用于更新目标行,但将使用哪一行不容易预测。

解决方案

所有这些考虑到您的查询可能如下所示:

UPDATE transakcje t
SET    s_dzien = c.dzien
     , s_cena  = c.price
FROM  (
    SELECT DISTINCT ON (dzien)
           dzien, price
    FROM   ciagle
    ORDER  BY dzien, price DESC
   ) c
WHERE t.k_dzien = c.dzien
AND  (t.s_dzien IS DISTINCT FROM c.dzien OR
      t.s_cena  IS DISTINCT FROM c.price)
  • 获取dzien子查询中ciagleDISTINCT ON的每个max()的最高价格。详细信息:
    Select first row in each GROUP BY group?@wildplasser commented一样,如果您需要的是最高价格,您也可以使用汇总函数DISTINCT ON代替... FROM ( SELECT dzien, max(price) AS price FROM ciagle GROUP BY czien ) c ...

    transakcje
  • s_dzien最终在k_dzienciagle中的相同行中显示相同的值。

  • 添加的WHERE子句阻止了您可能不想要的空更新:只有成本且没有效果(除了触发器的异常特殊情况等) - 一个常见的疏忽。