在这个查询中可以避免子查询吗?

Posted

技术标签:

【中文标题】在这个查询中可以避免子查询吗?【英文标题】:Can sub-query be avoided in this query? 【发布时间】:2020-08-30 11:34:57 【问题描述】:

我的数据库中的三个表如下:

教师桌teachers: teacher_id, teacher_name 学生桌students: student_id, student_name 教师-学生有一个多对多的关系,因此他们有一个专用表as per this answer:students_volunteers: teacher_id (FK), student_id(FK)

现在假设一位老师不能上课,所以他/她发布了一个替代请求,所以我们只想向那些有相同学生的老师发送通知。所以我写了相同的 SQL 查询:

SELECT DISTINCT students_volunteers.v_id_sv 
FROM   students_volunteers 
WHERE  students_volunteers.s_id_sv IN (SELECT students_volunteers.s_id_sv 
                                       FROM   students_volunteers 
                                       WHERE  v_id_sv = 3) 
       AND students_volunteers.v_id_sv <> 3 

它工作正常,只是它有一个子查询,由于性能问题并不理想。 所以我想知道我们是否可以使用一些JOIN 或其他东西来提高性能.....

【问题讨论】:

不应该有性能问题。您可以尝试任何其他方法,但此查询将提供同等甚至更好的性能。 一些针对 many:many 表的一般性能提示:mysql.rjweb.org/doc.php/… 【参考方案1】:

你可以试试not exists:

SELECT DISTINCT teacher_id
FROM students_volunteers sv
WHERE 
    teacher_id <> 3
    AND EXISTS (
        SELECT 1
        FROM students_volunteers sv1
        WHERE sv1.teacher_id = 3 AND sv1.student_id = sv.student_id
    )

或者,这里有一个带有 self-join 的方法:

SELECT DISTINCT sv.teacher_id
FROM students_volunteers sv
INNER JOIN students_volunteers sv1
    ON sv1.teacher_id <> sv.teacher_id
    AND sv1.student_id = sv.student_id
WHERE sv1.teacher_id = 3

【讨论】:

以上是关于在这个查询中可以避免子查询吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 Oracle 中避免相关子查询

是否可以避免这种查询的子查询?

BigQuery 避免多个子查询

MySQL笔记--- 连接查询;子查询;union;limit;

mysql的分页使用子查询?

返回链接记录并避免多个子查询/循环