对行总和的约束
Posted
技术标签:
【中文标题】对行总和的约束【英文标题】:Constraint on sum from rows 【发布时间】:2016-05-09 13:20:44 【问题描述】:我在 PostgreSQL 9.4 中有一张表:
user_votes (
user_id int,
portfolio_id int,
car_id int
vote int
)
是否可以在表格上设置一个约束,以便用户在每个投资组合中最多可以有 99 个点进行投票? 这意味着一个用户可以拥有多行,其中包含相同的 user_id 和 portfolio_id,但不同的 car_id 和 vote。总票数不应超过 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)
【问题讨论】:
【参考方案1】:很遗憾,如果您尝试创建这样的constraint,您将看到以下错误消息:
ERROR: aggregate functions are not allowed in check constraints
但关于 postgresql 的奇妙之处在于,总是有不止一种方法可以给猫剥皮。您可以使用 BEFORE trigger 来检查您尝试插入的数据是否满足我们的要求。
BEFORE 触发的行级触发器可以返回 null 来表示触发器 经理跳过该行的其余操作(即, 随后的触发器不会被触发,并且 INSERT/UPDATE/DELETE 会 此行不会发生)。如果返回非空值,则 操作继续该行值。
在您的触发器中,您将计算投票数
SELECT COUNT(*) into vote_count FROM user_votes WHERE user_id = NEW.user_id
现在如果 vote_count 是 99 你返回 NULL 并且数据不会被插入。
【讨论】:
以上是关于对行总和的约束的主要内容,如果未能解决你的问题,请参考以下文章