确定 MySQL 多对多关系中的记录缺失

Determining record absence in MySQL many-to-many relationship

我有一个简单的应用程序,可以向用户显示多项选择题并允许他们回答这些问题。这是我的表格:

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    |                |
+---------------------------------+---------------------+------+-----+---------+----------------+

我正在尝试设计一个查询来查找 questions 尚未询问的特定 user_id 。我最好的尝试是:

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
);

但这总是returns一个空集。我只想要一个 SELECT 查询,它告诉我特定用户尚未回答哪些问题。 有什么想法吗?

如果您想要未被问到的问题列表,则无法查询 multiple_choice_responses table。 table 包含用户和已提出问题之间的链接。

相反,查询 multiple_choice_questions table,并过滤掉任何已经提出的问题。

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
);