【问题标题】:MySQL get quiz score from quiz with questions having multiple correct answersMySQL 从具有多个正确答案的问题的测验中获取测验分数
【发布时间】:2021-05-13 08:24:56
【问题描述】:

我正在尝试从我的数据库中获取测验分数,基本上一个测验问题可以有多个正确答案,但要将该答案计为正确答案,用户必须选择该问题的所有正确答案。

例如如果用户只检查了 1 个正确的答案,但测验问题有多个正确的选项,则认为用户的答案不正确且不计入。

CREATE TABLE IF NOT EXISTS users (
    id              INT(10)             AUTO_INCREMENT,
    email           VARCHAR(255)        NOT NULL,
    fullName        VARCHAR(100)        NOT NULL,
    password        VARCHAR(255)        NOT NULL,
    admin           TINYINT(1)          DEFAULT 0,
    active          VARCHAR(255)        NOT NULL,
    resetToken      VARCHAR(255)        DEFAULT NULL,
    resetComplete   VARCHAR(3)          DEFAULT 'No',
    dor             TIMESTAMP, /* dor = Date of Registration */
    PRIMARY KEY(id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS unit (
    id          INT(10)         AUTO_INCREMENT,
    name        VARCHAR(100)    NOT NULL,
    published   TINYINT(1)      DEFAULT 0,
    unit_img    INT(10),
    PRIMARY KEY(id),
    FOREIGN KEY (unit_img) REFERENCES files(id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS files (
    id          INT(10)         AUTO_INCREMENT,
    file_name   VARCHAR(255)    NOT NULL,
    loc_name    VARCHAR(255)    NOT NULL,
    PRIMARY KEY(id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS quiz (
    id      INT(10)         AUTO_INCREMENT,
    unit_id INT(10)         NOT NULL,
    name    VARCHAR(100)    NOT NULL,
    published   TINYINT(1)      DEFAULT 0,
    PRIMARY KEY(id),
    FOREIGN KEY (unit_id)   REFERENCES unit(id)     ON DELETE CASCADE
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS quiz_question (
    id                  INT(10)         AUTO_INCREMENT,
    quiz_id             INT(10)         NOT NULL,
    question            VARCHAR(255)    NOT NULL,
    -- correct_answer      INT(10)         NOT NULL,
    question_img        INT(10),
    PRIMARY KEY (id),
    FOREIGN KEY (quiz_id)           REFERENCES  quiz(id)    ON DELETE CASCADE,
    FOREIGN KEY (question_img)      REFERENCES  files(id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS quiz_answer (
    id  INT(10) AUTO_INCREMENT  NOT NULL,
    question_id INT(10)         NOT NULL,
    choice      VARCHAR(150)    NOT NULL,
    is_correct  TINYINT(1)      DEFAULT 0, -- If = 1 then it is a correct answer
    PRIMARY KEY (id),
    FOREIGN KEY (question_id)   REFERENCES  quiz_question(id)   ON DELETE CASCADE
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE user_quiz_answers (
    id int(10)          AUTO_INCREMENT,
    user_id int(10)     NOT NULL,
    question_id int(10) NOT NULL,
    answer int(10)      NOT NULL,
    PRIMARY KEY (id),
    FOREIGN KEY (user_id)       REFERENCES  users(id)           ON DELETE CASCADE,
    FOREIGN KEY (question_id)   REFERENCES  quiz_question(id),
    FOREIGN KEY (answer)        REFERENCES  quiz_answer(id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `users` (`id`, `email`, `fullName`, `password`, `admin`, `active`, `resetToken`, `resetComplete`, `dor`) VALUES (NULL, 'test@gmail.com', 'Gerald', 'abc123', '1', 'YES', NULL, 'No', current_timestamp());

INSERT INTO `unit` (`id`, `name`, `published`, `unit_img`) VALUES (NULL, 'Motorbike', '1', NULL);

INSERT INTO `quiz` (`id`, `unit_id`, `name`, `published`) VALUES (NULL, '1', 'Final Exam', '1');

INSERT INTO `quiz_question` (`id`, `quiz_id`, `question`, `question_img`) VALUES (NULL, '1', 'Which parts of a motorbike should be lubricated?', NULL);

INSERT INTO `quiz_answer` (`id`, `question_id`, `choice`, `is_correct`) VALUES (NULL, '1', 'Chain', '1');
INSERT INTO `quiz_answer` (`id`, `question_id`, `choice`, `is_correct`) VALUES (NULL, '1', 'Break lines', '1');
INSERT INTO `quiz_answer` (`id`, `question_id`, `choice`, `is_correct`) VALUES (NULL, '1', 'Tyres', '0');

INSERT INTO `user_quiz_answers` (`id`, `user_id`, `question_id`, `answer`) VALUES (NULL, '1', '1', '1');

尝试:

SELECT COUNT(DISTINCT(uqa.question_id)) FROM user_quiz_answers uqa
LEFT JOIN quiz_question qq ON uqa.question_id=qq.id
LEFT JOIN quiz_answer qa ON uqa.answer=qa.id
WHERE uqa.user_id=1 AND qq.quiz_id=1 AND uqa.answer IN (SELECT qa.id FROM quiz_answer qa WHERE qa.is_correct=1);

qa.is_correct(0 = 不是正确答案,1 = 是正确答案)

以上是我到目前为止所拥有的,这几乎可以工作,除非它计算一个正确的答案,只要用户得到正确的问题中的一个选项,即当我希望这被认为是不正确且不被计算在内时.

编辑: 基本上我需要检查以下两个查询以返回相同的结果:

-- GET correct answers for question
(SELECT qa.id FROM quiz_answer qa WHERE qa.is_correct=1 AND qa.question_id=1);

-- Get user answers for question
(SELECT uqa.answer FROM user_quiz_answers uqa WHERE uqa.question_id=1 AND uqa.user_id=1);

编辑 2: 这是一个 SQLFiddle http://sqlfiddle.com/#!9/5ac0f/1

【问题讨论】:

  • @Strawberry 谢谢,我已经编辑了我的原始帖子。

标签: mysql


【解决方案1】:

我认为下面的代码会解决你的问题。

SELECT COUNT(DISTINCT (uqa.question_id))
FROM user_quiz_answers uqa
JOIN quiz_question qq ON uqa.question_id = qq.id  
WHERE uqa.question_id NOT IN ( 
           
        SELECT a.question_id FROM 
            (SELECT qa.question_id ,qa.id FROM quiz_answer qa WHERE qa.is_correct = 1) a
        LEFT JOIN 
            (SELECT uqa.question_id ,uqa.answer FROM user_quiz_answers uqa ) b
        ON a.question_id = b.question_id AND a.id = b.answer
        WHERE b.answer IS NULL
        
        UNION
        
        SELECT a.question_id FROM 
            (SELECT qa.question_id ,qa.id FROM quiz_answer qa WHERE qa.is_correct = 0)  a
        JOIN 
            (SELECT uqa.question_id ,uqa.answer FROM user_quiz_answers uqa) b
        ON a.question_id = b.question_id AND a.id = b.answer      
)
and quiz_id=1 and user_id=1;

代码说明:这部分代码将获取未检查所有答案的问题ID。

SELECT a.question_id FROM 
                (SELECT qa.question_id ,qa.id FROM quiz_answer qa WHERE qa.is_correct = 1) a
            LEFT JOIN 
                (SELECT uqa.question_id ,uqa.answer FROM user_quiz_answers uqa ) b
            ON a.question_id = b.question_id AND a.id = b.answer
            WHERE b.answer IS NULL

代码的下一部分将获取选中错误选项的所有问题 ID

SELECT a.question_id FROM 
                (SELECT qa.question_id ,qa.id FROM quiz_answer qa WHERE qa.is_correct = 0)  a
            JOIN 
                (SELECT uqa.question_id ,uqa.answer FROM user_quiz_answers uqa) b
            ON a.question_id = b.question_id AND a.id = b.answer

现在我们得到了所有不正确的问题 ID。所以我们从用户答案表 (WHERE uqa.question_id NOT IN) 中删除了这个问题 ID,并计算了剩余的问题,这些问题给出了正确回答的问题。

【讨论】:

  • 您好,感谢您的回复,这似乎适用于 question_id=n 的单个问题。但是假设我希望它返回整个测验的总分 (quiz_id= n)?
  • 验证我删除问题ID过滤器的更新代码,现在您还可以根据测验ID和用户ID进行过滤
  • 嗨,这个查询在我的本地 XAMP mysql 数据库上运行良好,但是当我在我的实时网站上重新创建时,我收到了一个错误。通过 SQL Fiddle 运行时,我也会出现同样的错误,你知道为什么会这样吗? You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION ( SELECT a.question_id FROM ' at line 15
  • 我在 xamp 中测试后也发布了代码。现在我删除了包裹在我之前的联合块上的额外括号,它现在可以工作了。希望对你有帮助
猜你喜欢
  • 2020-01-06
  • 1970-01-01
  • 1970-01-01
  • 2015-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多