Postgres 9.6.x:如何从主表自动更新辅助表?

时间:2017-08-06 16:32:38

标签: database postgresql sequelize.js

我有一个小测验应用,我想跟踪每个问题被正确和错误地回答的次数。有三个表:Questions,Playthrus和AnswerCounts。在Playthrus表中,我捕获了(1)incorrect_answer,这是由于错误答案而结束测验的问题的主键 int ;和(2)correct_answers,这是一个数组正确回答问题的主键。

AnswerCounts表有三列:idcorrect_countincorrect_countid映射到问题表ID。

我的问题是:如何设置我的postgres数据库,以便每当向Playthrus表提交新行时,(1)创建或更新incorrect_answer和{{中找到的所有主键的行1}}列; (2)correct_answerscorrect_count相应增加?

或者,我是否错误地处理了这个问题并且有一个更好的方法?

我使用的是Postgres 9.6.3和Sequelize。

编辑:在下面的每个响应中,我抛弃了增量触发器并创建了一个新表,Answers。

incorrect_count

我使用给定的playthru更新此表,包含所有答案,正确和错误。

查询确定问题的答案是否正确最多且错误最多:

CREATE TABLE answers(
  id serial primary key,
  question_id int REFERENCES questions (id),
  playthru_id int REFERENCES playthrus (id),
  was_correct boolean
);

2 个答案:

答案 0 :(得分:1)

在postgresql doc中查看CREATE TRIGGER

答案 1 :(得分:1)

规范化规则会说你应该放弃正确答案"数组支持单独的表,每个答案一行。这可以引用" playthru"的主键,问题的主键,以及布尔"是正确的"柱。这也为您在当前设计中捕获的其他数据留出了空间,例如给出的实际答案,甚至可能在问题上花了多长时间等等。

您可以使用array_agg函数在选择查询中取回现有数组,甚至可以加入完整的问题并获取其文本数组,而不仅仅是ID。

重要的是,您可以随时计算正确和错误的计数:按问题ID分组和"是正确的",并输出计数(*)。要在一行中获得正确和错误以便于处理,您可以使用如下的case语句:

SELECT
    question_id,
    COUNT(CASE WHEN was_correct THEN 1 END) as correct_answers,
    COUNT(CASE WHEN NOT was_correct THEN 1 END) as incorrect_answers
FROM playthru_questions
GROUP BY question_id

这里的技巧是COUNT忽略CASE不匹配的空值,并计算与条件匹配的行。