必须同时存在同一列上具有多个WHERE条件的SELECTING

时间:2013-01-03 07:19:59

标签: php mysql

我看过很多帖子,但没有得到我的回答我有一个结构表

 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

3 个答案:

答案 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