【问题标题】:mysql select rows not in many-to-many relationmysql选择不在多对多关系中的行
【发布时间】:2012-07-18 22:38:09
【问题描述】:

我有一个数据结构,其中学生和小组之间存在多对多关系。我有三张桌子

学生:身份证、姓名

组:ID、名称

students_groups:student_id、group_id

如何只选择不属于特定组的学生(例如 group.id = 1)?

我做了一些搜索并尝试使用子查询但只得到一个空集...

select * from students where not exists (select students.* from students left join students_groups on students_groups.student_id = student.id where students_groups.group_id = 1);

我应该如何查询?提前谢谢!

编辑 好的,看来以下两个终于可以工作了...有人可以向我解释为什么我不需要加入表格就可以工作吗???

select * from students where not exists (select * from students_groups where students_groups.student_id = student.id and student_groups.group_id = 1);

select * from students where id not in (select student_id from students_groups where group_id = 1);

【问题讨论】:

    标签: php mysql sql


    【解决方案1】:

    使用NOT IN 应该可以正常工作:

    SELECT * FROM Students
    WHERE Id NOT IN (
        SELECT Student_Id FROM Students_Groups
        WHERE Group_Id = 1)
    

    【讨论】:

    • 谢谢博特。实际上,我也只是想通了(请参阅我的编辑)。你能解释一下为什么我不需要加入表格,我会选择作为答案。谢谢!
    • 由于您要做的只是找到不在第 1 组中的任何学生,因此您选择所有在第 1 组中的学生的 id,并使用 @ 987654323@ 检查您选择的学生的 ID 是否不是其中之一。使用连接也可以。
    • 你的答案为什么有效是有道理的。但为什么我最初的回答没有加入工作?我只有一个空集
    • @bort 我应该给你买个车牌。
    • @wootscootinboogie 别打扰,他们都出来了。
    【解决方案2】:

    编辑后的问题要求解释。

    将 SQL 查询视为文本中的Venn Diagrams。每个子句要么定义一个内容圈,要么告诉您您对整个重叠圈图的哪一部分感兴趣。

    select * from students where id not in (select student_id from students_groups where group_id = 1);
    

    一个圆圈是学生桌。一个圆圈是 student_groups 表,其中 group_id = 1。圆圈重叠,students.id 等于 student_groups.student_id。您希望学生表中在重叠区域中的部分。

    您不需要连接这些表,因为您的结果集仅包含来自学生表的数据。您正在使用另一个表来限制该结果集,而不是为您的结果提供数据。

    【讨论】:

      【解决方案3】:

      未经测试,但以下其中一项应该可以工作。你必须做一些explaining 看看哪个最好。

      select * 
      from students 
      where not exists (select *
                        from students_groups 
                        where students_groups.student_id = student.id 
                        and students_groups.group_id = 1)
      

      或者...

      select * 
      from students 
      where id not in (select student_id
                        from students_groups 
                        where group_id = 1)
      

      或者...

      select students.id, students.name 
      from students 
      left outer join students_groups on students.id = students_groups.student_id
                                      and students_groups.group_id = 1
      where students_groups.student_id is null
      group by students.id, students.name
      

      【讨论】:

        【解决方案4】:

        你可以试试这样的:

        SELECT
            *
        FROM
            students
        WHERE
            id NOT IN
                ((SELECT 
                    student_id
                FROM
                    students_groups
                WHERE
                    group_id = 1
                ))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-03-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-09-26
          • 1970-01-01
          • 1970-01-01
          • 2011-04-12
          相关资源
          最近更新 更多