简体   繁体   中英

Determining record absence in MySQL many-to-many relationship

I have a simple app that presents users with multiple choice questions and allows them to answer those questions. Here are my tables:

mysql> describe users;
+-------------------------------+---------------------+------+-----+---------+----------------+
| Field                         | Type                | Null | Key | Default | Extra          |
+-------------------------------+---------------------+------+-----+---------+----------------+
| user_id                       | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| user_status_id                | bigint(20) unsigned | NO   | MUL | NULL    |                |
| profile_id                    | bigint(20) unsigned | YES  | MUL | NULL    |                |
+-------------------------------+---------------------+------+-----+---------+----------------+

mysql> describe multiple_choice_questions;
+----------------------------------+---------------------+------+-----+---------+----------------+
| Field                            | Type                | Null | Key | Default | Extra          |
+----------------------------------+---------------------+------+-----+---------+----------------+
| multiple_choice_question_id      | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| multiple_choice_question_text    | varchar(500)        | NO   |     | NULL    |                |
+----------------------------------+---------------------+------+-----+---------+----------------+

mysql> describe multiple_choice_options;
+------------------------------------+---------------------+------+-----+---------+----------------+
| Field                              | Type                | Null | Key | Default | Extra          |
+------------------------------------+---------------------+------+-----+---------+----------------+
| multiple_choice_option_id          | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| multiple_choice_option_name        | varchar(250)        | NO   | UNI | NULL    |                |
| multiple_choice_option_label       | varchar(250)        | NO   | UNI | NULL    |                |
| multiple_choice_option_description | varchar(500)        | NO   |     | NULL    |                |
+------------------------------------+---------------------+------+-----+---------+----------------+

mysql> describe questions_x_mc_options;
+------------------------------+---------------------+------+-----+---------+----------------+
| Field                        | Type                | Null | Key | Default | Extra          |
+------------------------------+---------------------+------+-----+---------+----------------+
| questions_x_mc_option_id     | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| multiple_choice_question_id  | bigint(20) unsigned | NO   | MUL | NULL    |                |
| multiple_choice_option_id    | bigint(20) unsigned | NO   | MUL | NULL    |                |
+------------------------------+---------------------+------+-----+---------+----------------+

mysql> describe multiple_choice_responses;
+---------------------------------+---------------------+------+-----+---------+----------------+
| Field                           | Type                | Null | Key | Default | Extra          |
+---------------------------------+---------------------+------+-----+---------+----------------+
| multiple_choice_response_id     | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| user_id                         | bigint(20) unsigned | NO   | MUL | NULL    |                |
| multiple_choice_question_id     | bigint(20) unsigned | NO   | MUL | NULL    |                |
| multiple_choice_option_id       | bigint(20) unsigned | NO   | MUL | NULL    |                |
+---------------------------------+---------------------+------+-----+---------+----------------+

I'm trying to devise a query that will look for questions that a particular user_id has not been asked yet. My best attempt is:

SELECT *
FROM multiple_choice_responses
WHERE multiple_choice_question_id NOT IN (
  SELECT multiple_choice_question_id
  FROM multiple_choice_responses
  WHERE user_id = 1
);

But this always returns an empty set. I just want a SELECT query which tells me which questions a particular user hasn't answered yet. Any ideas?

You can't query the multiple_choice_responses table if you want a list of questions which have not been asked. That table contains links between users and questions which have been asked.

Instead, query the multiple_choice_questions table, and filter out any questions which have already been asked.

SELECT *
FROM multiple_choice_questions
WHERE multiple_choice_question_id NOT IN (
    SELECT multiple_choice_question_id
    FROM multiple_choice_responses
    WHERE user_id = 1
);

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