我看过很多帖子,但没有得到我的回答我有一个结构表
subject_level_id | tutor_id | level_id_fk | subject_id_fk |
118 | 99 | 4 | 1 |
119 | 99 | 3 | 2 |
120 | 99 | 3 | 3 |
121 |100 | 3 | 1 |
122 |100 | 4 | 2 |
我想提取导师的导师ID,他们教授特定级别的1,2或更多科目(科目数量取决于用户对科目的选择,但是水平对于特定查询是唯一的)
我已经在其他帖子的帮助下制定了一个查询,但是如果主题数量超过两个,它会非常慢并且会变得更糟,因为我有10,000条导师记录,我的查询是:
select distinct
a.tutor_id
from
tutor_preferred_level_subject as a
inner join
tutor_preferred_level_subject as b
on a.level_id_fk = b.level_id_fk
where
a.subject_id_fk = 1 and
b.subject_id_fk = 10 and
a.level_id_fk = 3
建议:SELECTING with multiple WHERE conditions on same column
这个问题和我的不同之处在于,我希望教师能够完全教授这两个科目。
更新:是主要关注的是性能,这个查询对于两个主题工作正常但是对于两个以上的主题,mysql服务器将继续处理。索引为subject_level_id
,其中有近13000条记录,以下查询返回约6500条结果。
正如Jakub Sacha所要求的那样是
的结果EXPLAIN select distinct
a.tutor_id
from
tutor_preferred_level_subject as a
inner join
tutor_preferred_level_subject as b
on a.level_id_fk = b.level_id_fk
where
a.subject_id_fk = 1 and
b.subject_id_fk = 10 and
a.level_id_fk = 3
id select_type table type possible_keys key key_len ref|
1 SIMPLE a ALL NULL NULL NULL NULL
1 SIMPLE b ALL NULL NULL NULL NULL
rows Extra
12733 Using where; Using temporary
12733 Using where; Distinct
答案 0 :(得分:2)
您的查询似乎没有按照您的描述进行操作。联接应位于tutor_id
而不是level_id_fk
。
仅当DISTINCT
组合不唯一时才需要(level_id_fk, subject_id_fk, tutor_id)
:
SELECT
-- DISTINCT
a.tutor_id
FROM
tutor_preferred_level_subject AS a
INNER JOIN
tutor_preferred_level_subject AS b
ON a.tutor_id = b.tutor_id
WHERE
a.subject_id_fk = 1 AND
a.level_id_fk = 3 AND
b.subject_id_fk = 10 AND
b.level_id_fk = 3 ;
此外,您应在(level_id_fk, subject_id_fk, tutor_id)
上添加(唯一)索引以提高效率:
ALTER TABLE tutor_preferred_level_subject
ADD INDEX level_subject_tutor_IDX
(level_id_fk, subject_id_fk, tutor_id) ;
答案 1 :(得分:1)
这将选择所有具有两个不同主题匹配的tutor_id(1,10):
SELECT
Distinct tutor_id
FROM
tutor_preferred_level_subject
WHERE
level_id_fk = 3
GROUP BY tutor_id, level_id_fk
HAVING
Count(Distinct subject_id_fk) = 2 AND
Sum(subject_id_fk NOT IN (1, 10)) = 0
答案 2 :(得分:0)
似乎你不需要将表内连接到自身,这就是当你获得越来越多的行时会导致缓慢的行为。
你说你需要“教授1,2或更多特定水平科目的导师”,这基本上只是意味着你需要教导那个特定水平的导师。因此,尝试分组并使用HAVING子句(这将要求您的数据当然是干净的)
SELECT a.tutor_id
FROM tutor_preferred_level_subject AS a
WHERE a.subject_id_fk IN (1,10)
AND a.level_id_fk = 3
GROUP BY a.tutor_id
HAVING COUNT(1) > 1