1

我有表问题、主题和 question_has_topic(多对多关系)。在我的应用程序中,管理员会看到按主题分组的问题的细分,他们会从每个问题中选择他们希望系统随机选择的数量来创建测试。
这是他们看到的那种表:

+------------------------+----------+--- ---------+
| 话题 | 可用问题 | 选择: |
+------------------------+----------+--- ---------+
| 健康、安全、通用| 13 | |
| 健康 | 3 | |
| 安全 | 7 | |
| 一般| 1 | |
+------------------------+----------+--- ---------+

该计数对于特定的主题分组是唯一的。无论如何,一旦他们做出选择,我需要一个 SQL 语句来选择与给定主题分组相对应的问题。即我可能需要 3 个问题,主题为健康、安全和一般。
我在网上做了一些研究,我认为我正在尝试做的事情被称为关系代数中的划分,这是我对主题的任意分组的尝试:

从 question_has_topic 中选择 questionid
不存在的地方(
    从 question_has_topic 中选择 questionid
    其中 topicid 不在 (8,9,10))

结果是空的,尽管数据库中有 2 个问题具有所有这些主题 ID,这告诉我这不起作用。我正在关注此链接中的示例

4

2 回答 2

2

我认为这是你试图写的,但这是一种非常低效的方式 -

SELECT questionid FROM question WHERE NOT EXISTS (
    SELECT topicid FROM topic WHERE topicid NOT IN (
        SELECT topicid FROM question_has_topic WHERE question.questionid = question_has_topic.questionid
    ) AND topicid IN (8, 9, 10)
);

这肯定要快得多-

SELECT *
FROM question_has_topic t1
INNER JOIN question_has_topic t2
    ON t1.questionid = t2.questionid AND t2.topicid = 9
INNER JOIN question_has_topic t3
    ON t2.questionid = t3.questionid AND t3.topicid = 10
WHERE t1.topicid = 8;

更新:我知道有一个更简单的答案。Cheran 的方法要简单得多,运行速度应该比 INNER JOIN 稍快。请接受他的回答。

于 2012-02-20T02:53:58.450 回答
2

编辑:删除了我的旧帖子,因为我误读了这个问题。


这是我过去使用的一种技术:

  SELECT qht.questionid
    FROM question_has_topic AS qht
   WHERE qht.topicid IN (8,9,10)
GROUP BY qht.questionid
  HAVING COUNT(*) = 3 AND
         COUNT(*) = (SELECT COUNT(*) FROM question_has_topic AS dupe
                     WHERE dupe.questionid = qht.questionid)

其中3对应于给定组中的主题数。这假设其中的每一(questionid, topicid)question_has_topic都是唯一的(它应该在多对多关系表中)。

此查询的工作方式是首先选择具有至少一个指定主题的任何问题 ( WHERE qht.topicid IN (8,9,10)),然后按 分组questionid。第一个 HAVING 子句 ( COUNT(*) = 3) 仅在给定问题分配了所有三个主题时才为真(因为我们假设此表中不允许重复)。第二个 HAVING 子句检查分配给问题的主题总数。这是为了防止出现这样的情况,例如,一个问题可能分配有主题 8、9、10 和 11。

于 2012-02-20T06:07:53.120 回答