【问题标题】:Updating a row based on a value from another table?根据另一个表中的值更新行?
【发布时间】:2022-01-10 07:17:15
【问题描述】:

所以我有两个表“books”和“bookOrder”,它们看起来像这样:

bookOrder

| orderID | book name   | required | availability
| --------|-------------| ---------| ------------|
| 1       |Harry Potter | 9        | yes         |
| 2       |Twilight     | 8        | yes         |
| 3       |Bible        | 8        | yes         |

books

|book name   |quantity|
|------------|--------|
|Harry Potter|10      |
|Twilight    |5       |
|Bible       |8       |

我希望能够根据“books”表更新“bookOrder”可用性列。

目前我的SQL查询如下:

UPDATE bookOrder
SET avalability = case when (
SELECT quantity
FROM books
WHERE books.bookName = bookOrder.bookName
) < (SELECT required From bookOrder WHERE bookOrder.bookName = books.bookName) THEN 'NO' END;

但我收到一个错误:

missing FROM-clause entry for table "books"

我可能只是查询完全错误。

(P.S. 我知道有人想买 8 本《暮光之城》的书是完全荒谬的。)

【问题讨论】:

    标签: sql postgresql sql-update


    【解决方案1】:

    UPDATE syntax 用作advised by Tim Biegeleisen,但再添加一个WHERE 条件:

    UPDATE bookOrder bo
    SET    availability = CASE WHEN b.quantity < bo.required THEN 'NO' ELSE 'YES' END
    FROM   books b
    WHERE  b.bookName = bo.bookName
    AND    bo.availability IS DISTINCT FROM CASE WHEN b.quantity < bo.required THEN 'NO' ELSE 'YES' END;
    

    这样,Postgres 只会写入值实际发生变化的新行版本。这会对写入性能和一般数据库性能产生重大影响。见:

    availability 应该是数据类型boolean,在这种情况下你可以简化:

    UPDATE bookOrder bo
    SET    availability = (b.quantity >= bo.required)
    FROM   books b
    WHERE  b.bookName = bo.bookName
    AND    bo.availability IS DISTINCT FROM (b.quantity >= bo.required);
    

    如果使用 FK 约束强制执行参照完整性,并且所有涉及的列都定义为 NOT NULL,请进一步简化:

    ...
    AND    bo.availability <> (b.quantity >= bo.required);
    

    或者完全删除该列并动态查找availability。这样的属性在到达时可能会过时。您可以为此使用VIEW

    CREATE VIEW book_order_plus AS
    SELECT bo.*, (b.quantity >= bo.required) AS availability
    FROM   bookOrder bo
    LEFT   JOIN books b USING (bookName);
    

    哦,使用合法的、小写的、不带引号的标识符来保持 Postgres 的生活简单。见:

    【讨论】:

      【解决方案2】:

      我会在这里使用更新连接:

      UPDATE bookOrder bo
      SET availability = CASE WHEN b.quantity < bo.required THEN 'NO' ELSE 'YES' END
      FROM books b
      WHERE b.bookName = bo.bookName
      

      【讨论】:

        猜你喜欢
        • 2012-11-27
        • 1970-01-01
        • 2018-08-02
        • 2023-03-26
        • 1970-01-01
        • 2012-09-05
        • 1970-01-01
        相关资源
        最近更新 更多