对行总和的约束

Constraint on sum from rows

我在 PostgreSQL 9.4 中有一个 table:

user_votes (
  user_id int,
  portfolio_id int,
  car_id int
  vote int
)

是否可以对 table 施加限制,以便用户最多可以在每个投资组合中拥有 99 点的投票权? 这意味着用户可以有多行,其中包含相同的 user_id 和 portfolio_id,但不同的 car_id 和投票。票数总和不能超过99,但可以放在不同的车上。

这样做:

INSERT INTO user_vores (user_id, portfolio_id, car_id, vote) VALUES
    (1, 1, 1, 20),
    (1, 1, 7, 40),
    (1, 1, 9, 25)

都可以,但是当尝试添加超过 99 票的内容时应该会失败,就像另一行:

    INSERT INTO user_vores (user_id, portfolio_id, car_id, vote) VALUES
    (1, 1, 21, 40)

很遗憾,如果您尝试创建这样的 constraint,您将看到此错误消息:

ERROR: aggregate functions are not allowed in check constraints

但是 postgresql 的奇妙之处在于,总是有不止一种方法可以给猫剥皮。您可以使用 BEFORE trigger 来检查您尝试插入的数据是否满足我们的要求。

Row-level triggers fired BEFORE can return null to signal the trigger manager to skip the rest of the operation for this row (i.e., subsequent triggers are not fired, and the INSERT/UPDATE/DELETE does not occur for this row). If a nonnull value is returned then the operation proceeds with that row value.

在你的触发器中你会计算投票数

 SELECT COUNT(*) into vote_count FROM user_votes WHERE user_id = NEW.user_id

现在如果 vote_count 是 99 你 return NULL 并且数据将不会被插入。