我有一个小测验应用,我想跟踪每个问题被正确和错误地回答的次数。有三个表:Questions,Playthrus和AnswerCounts。在Playthrus表中,我捕获了(1)incorrect_answer
,这是由于错误答案而结束测验的问题的主键 int ;和(2)correct_answers
,这是一个数组正确回答问题的主键。
AnswerCounts表有三列:id
,correct_count
和incorrect_count
。 id
映射到问题表ID。
我的问题是:如何设置我的postgres数据库,以便每当向Playthrus表提交新行时,(1)创建或更新incorrect_answer
和{{中找到的所有主键的行1}}列; (2)correct_answers
和correct_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
);
答案 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不匹配的空值,并计算与条件匹配的行。