17

我需要使用从另一个表中删除的值来更新一个表。这种情况是类似于 SO 的评论投票记分员。我正在使用 python 来处理 postgres,但这不应该有所作为。

query="""
UPDATE comment SET score=score-(DELETE FROM history
                                WHERE commentId=%(commentId)s AND
                                      userIdentity=%(userIdentity)s RETURNING vote)
WHERE commentId=%(commentId)s;
"""
cursor.execute(query, data)

错误出现在(DELETE FROM; 出现语法错误。我可以用DELETE声明替换SELECT声明,它会起作用,这里有什么我遗漏的吗?我想在更新中使用返回值。这可能吗?任何事情都有帮助。

相关架构:

CREATE TABLE history (
    commentId bigint,
    vote int,
    userIdentity varchar(256),
);
CREATE TABLE comment (
    id bigint,
    score bigint,
);

history.vote 通常是1or -1

4

1 回答 1

28

PostgreSQL 不允许混合 UPDATE 和 DELETE 语句作为子查询。

您可以使用一些不同的策略 - 可更新 CTE

postgres=# WITH t1 AS (DELETE FROM foo RETURNING *),
                t2 AS (INSERT INTO 已删除
                          选择 * 从 t1 返回 *)
             从 t2 中选择 max(a);

所以

postgres=#CREATE TABLE 评论(id int,score int);
创建表
postgres=# CREATE TABLE 历史(id int,comment_id int,vote int);
创建表
postgres=#插入评论值(1,10);
插入 0 1
postgres=#插入评论值(2,20);
插入 0 1
postgres=#插入历史值(1,1,5);
插入 0 1
postgres=# WITH t1 AS (从历史中删除
                       哪里 id=1
                       返回comment_id,投票)
           更新评论 SET score=score-t1.vote
           从 t1
           哪里 t1.comment_id=comment.id;
更新 1
postgres=# 从评论中选择 *;
 编号 | 分数
----+-------
  2 | 20
  1 | 5
(2 行)

注意:它需要 9.1 或更高版本

于 2013-08-01T15:04:09.863 回答