我有一个用于跟踪用户在游戏中的进度的表格,如下所示:
create table progressions (
user_id int,
attempt_count int,
correct_count int,
accuracy float,
state text
);
我想创建一个查询,它将通过以下方式更新用户的进度:
现在,前三个点可以通过以下方式轻松实现:
update
progressions p
set
attempt_count = p.attempt_count + {attempt_count},
correct_count = p.correct_count + {correct_count},
accuracy = p.accuracy * (1 - {alpha}) + ({correct_count} / {attempt_count}::float) * {alpha}
where
user_id = {user_id};
当我想根据准确性更新状态时,问题出现了,我需要在条件中重用精度表达式的结果:
...
accuracy = {accuracy_expression},
state = case
when {accuracy_expression} > 0.9 then 'exceptional'
when {accuracy_expression} > 0.8 then 'pretty good'
...
end
...
我认为我可以在这种情况下使用CTE(可能存在原子性问题),但我想知道是否还有其他方法可以重复使用精度表达式的结果而不重新计算它?
如果没有,如果我重复N
次,PostgreSQL会在内部进行优化吗?
答案 0 :(得分:1)
您是否考虑过在更新触发器之前维护这些计算字段?
create function progressions_accuracy_upd() returns trigger as $$
begin
new.state := case
when new.accuracy > 0.9 then 'exceptional'
when new.accuracy > 0.8 then 'pretty good'
…
return new;
end;
$$ language plpgsql;
create trigger progressions_accuracy_upd before update on progressions
for each row when (new.accuracy is distinct from old.accuracy)
execute procedure progressions_accuracy_upd();
就此而言,您是否考虑直接在应用中计算州字段? (精确度字段更有意义,以便查询精度在x和y之间的玩家,但状态似乎不必要地存储与行数一样多的字符串。)