简体   繁体   中英

MySQL - How to select row were not selected in another table

I am creating multiple choice quiz web app with php and mysql; 10 questions for each quiz. Each time it will select 10 questions from database randomly and those selected qids are inserting into results table.

Currently, I have two tables; questions table for questions and options and results table to store selected questions.

My question is how to select questions that are not exists in results table? I have 100 questions in database, what about if user reaches last(100) question.

questions table:

+-------+---------------+----------------+
| qids  |   q_text      |  q_options     |
+-------+---------------+----------------+
|   1   |  example1     |opt1, opt2, opt3|
|   2   |  example2     |opt1, opt2, opt3|
|   3   |  example3     |opt1, opt2, opt3|
+-------+---------------+----------------+

results table:

+----+------------------------------+
| id |          qids                |
+----+------------------------------+
|  1 |   1,2,3,4,5,6,7,8,9,10       |
|  2 |11,12,13,14,15,16,17,18,19,20 |
+----+------------------------------+

The structure of your results table is not good for this purpose. You might want to use a hasMany relationship between results and questions.

You need to store each question asked in a separate row. For this I have demonstrated a third table (result_questions) that relates results to questions with in a hasMany relationship. That is: each result row has many questions.

questions table:

qids, q_text, q_options

results table:

id, anyothercolumn

result_questions table:

id, resultid, qid

In the result_questions table the id is auto increasing, the resultid is a foreign key from the results table, the qid is a foreign key from the questions table.

At the end we would end up with a table looking like this:

result_questions:

+----+----------+-----+
| id | resultid | qid |
+----+----------+-----+
|  1 |        1 |   1 |
|  2 |        1 |   2 |
|  3 |        1 |   3 |
|  4 |        1 |   4 |
|  5 |        1 |   5 |
|  6 |        1 |   6 |
|  7 |        1 |   7 |
|  8 |        1 |   8 |
|  9 |        1 |   9 |
| 10 |        1 |  10 |
| 11 |        2 |  11 |
| 12 |        2 |  12 |
| 13 |        2 |  13 |
| 14 |        2 |  14 |
| 15 |        2 |  15 |
| 16 |        2 |  16 |
| 17 |        2 |  17 |
| 18 |        2 |  18 |
| 19 |        2 |  19 |
| 20 |        2 |  20 |
+----+----------+-----+

Note: If questions are selected randomly the order of qids above would be random and not sequential.

Then you can use the query:

SELECT * FROM questions 
 WHERE id NOT IN (SELECT qid FROM result_questions) 
ORDER BY RAND() LIMIT 10;

That would give you questions that have not been asked. You would want to store them into the result_questions table after creating a new result row, so they don't get asked again.

Also, you might want to refactor how your options are being stored. Either use separate columns for each option if you know the maximum number of options or use a hasMany relationship for questions to options as well

I hope you are able to understand these.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM