1

我需要用另一个表中的值更新表中的 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;

但我得到一个错误:

计划不应引用子计划的变量。

DB 结构尽可能简单:transakcjehas k_dzien, k_cena, s_dzien, s_cenaand ciaglehas fields price, dzien.

我正在运行 PostgreSQL 9.3。

编辑

我想更新所有记录transakcjeciagle对于每一行,我必须从相同dzien和最大值中找到一行并将price其保存到.pricedzientransakcje

其中ciagle有许多行相同dzien(列不不同)。

4

1 回答 1

3

问题

您拥有的表格:

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

……一开始是违法的。正如错误消息告诉您的那样,子查询无法引用UPDATE子句中的表。列表中的项目FROM通常不能引用同一级别的其他项目(LATERALPostgres 9.3 或更高版本除外)。并且UPDATE子句中的表永远不能被子句中的子查询引用FROM(这在 Postgres 9.3 中没有改变)。

即使这是可能的,结果也将是无稽之谈,原因有两个:

  • 子查询LIMIT 1恰好产生一行(总计),而您显然需要一个特定的值 per dzien

    ciagle 的一排与相同的 dzien

  • 一旦你修改它并计算一个价格 per dzien,你最终会得到一个类似于交叉连接的东西,除非你添加一个WHERE条件来明确地将子查询的结果连接到要更新的表中。引用手册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)
  • 使用 .在子查询中获取每个dzienin的最高价格。详细信息:选择每个 GROUP BY 组中的第一行? 就像@wildplasser 评论的那样,如果您只需要最高价格,您也可以使用聚合函数而不是:ciagleDISTINCT ON
    max()DISTINCT ON

    ...
    FROM  (
       SELECT dzien, max(price) AS price 
       FROM   ciagle
       GROUP  BY czien
       ) c
    ...
    
  • transakcje最终在s_dzienk_dzien中存在相关行的位置具有相同的值ciagle

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

于 2013-11-01T02:09:12.547 回答