我有表格问题,主题和question_has_topic(多对多关系)。在我的应用程序管理员中,查看按主题分组的问题的细分,并选择他们希望系统随机选择创建测试的人数。 这是他们看到的那种表格:
+-----------------------+---------------------+------------+ | Topics | Questions available | Selection: | +-----------------------+---------------------+------------+ | health,safety,general | 13 | | | health | 3 | | | safety | 7 | | | general | 1 | | +-----------------------+---------------------+------------+
计数对于特定的主题分组是唯一的。无论如何,一旦他们做出选择,我需要一个SQL语句,它将选择与给定的主题分组相对应的问题。 即我可能需要3个问题,其主题是健康,安全和一般。我在网上进行一些研究,我认为我正在尝试做的事情被称为关系代数中的分歧,这是我尝试的任意分组的主题:
select questionid from question_has_topic where not exists ( select questionid from question_has_topic where topicid not in (8,9,10))
结果是空的,尽管数据库中有两个问题,其中包含所有这些主题ID,这些问题告诉我这不起作用。我正在关注此link
中的示例答案 0 :(得分: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快一些。请接受他的回答。
答案 1 :(得分: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的情况。