【问题标题】:Workaround for using aggregate function in WHERE for an UPDATE statement在 WHERE 中为 UPDATE 语句使用聚合函数的解决方法
【发布时间】:2018-02-07 02:24:57
【问题描述】:

我正在向使用 PostgreSQL 数据库的项目添加新功能。

数据库中有一个名为 brew_sessions 的表 - 它有一个名为 condition_date 的列。

brew_sessions 通过brew_sessions.recipe_id = recipes.id 连接到recipes 表。然后recipes 通过recipes.id = recipe_fermentation_steps.recipe_id 连接到另一个名为recipe_fermentation_steps 的表。

condition_date 小于或等于从condition_date 值计算的天数时,我想运行更新语句以将brew_sessions 字段上的status 字段设置为30。

这个值是recipe_fermentation_steps.time的总和。

例如:

SELECT
  brew_sessions.id,
  SUM(recipe_fermentation_steps.time)
FROM brew_sessions
  INNER JOIN recipes ON brew_sessions.recipe_id = recipes.id
  INNER JOIN recipe_fermentation_steps ON recipes.id = recipe_fermentation_steps.recipe_id
GROUP BY brew_sessions.id

这导致我进行以下查询:

UPDATE brew_sessions
SET status = 30 FROM recipes
  INNER JOIN recipe_fermentation_steps ON recipes.id = recipe_fermentation_steps.recipe_id
WHERE brew_sessions.recipe_id = recipes.id
AND brew_sessions.condition_date
    <= CURRENT_TIMESTAMP - INTERVAL '1 day' * SUM(recipe_fermentation_steps.time)

但是,这不会运行,因为您不能在 WHERE 中使用聚合函数。

如何正确写出上面的内容?

【问题讨论】:

    标签: sql postgresql sql-update aggregate-functions


    【解决方案1】:

    您可以使用子查询。喜欢:

    UPDATE brew_sessions b
    SET    status = 30
    FROM  (
       SELECT recipe_id, SUM(time) AS sum_time
       FROM   recipe_fermentation_steps
       GROUP  BY 1
       ) f
    WHERE  b.recipe_id = f.recipe_id
    AND    b.condition_date <= CURRENT_TIMESTAMP - INTERVAL '1 day' * f.sum_time;
    

    如果使用 FK 约束强制执行参照完整性,则根本不需要涉及表 recipes

    不过,这种方法值得商榷。通常,您不会将功能相关的值或取决于当前时间的值写入表中。为此使用VIEW(或MATERIALIZED VIEW)或类似名称。

    【讨论】:

    • 这是一个很大的帮助 - 我意识到我在我的问题中犯了一个错字。 condition_date 不需要与自身进行比较,包括时间间隔,它需要根据当前时间减去时间间隔进行测试。非常感谢您的帮助!
    • 非常好。但如果该值还取决于当前时间,那么 view 看起来会更好。
    • 这只是我需要运行的一次性更新。它设置得当,我只需要一种历史更新记录的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-19
    • 2010-09-28
    相关资源
    最近更新 更多