Mysql:连接五个表

时间:2013-11-07 16:23:04

标签: mysql sql join

我有一个带有此设置的mysql数据库(省略与此问题无关的字段)

users
  id                #primary key

user_group_teachers
  id                #primary key
  teacher_id        #foreign key to users.id
  user_group_id     #foreign key to users_groups.id

user_groups
  id                #primary key

user_group_members
  id                #primary key
  pupil_id          #foreign key to pupils.id
  user_group_id     #foreign key to users_groups.id

pupils
  id                #primary key

我在数组中有一组用户ID,名为“user_ids”。

对于每个用户ID,我想通过

收集与该用户相关的学生ID
user -> user_group_teachers -> user_groups -> user_group_members -> pupils

关联。即,各种各样的联合。

所以,我希望获得某些行的结果

[1, [6,7,8,9]]

其中1是教师ID,[6,7,8,9]是学生的ID。我只希望每个学生ID在第二个列表中出现一次。

任何人都可以告诉我如何在尽可能少的查询中(或者更广泛地,尽可能有效地)进行此操作。我可能通常在user_ids中有1000到10,000个ID。

我在ruby脚本中执行此操作,因此可以将结果作为变量(数组或散列)存储在查询之间,如果这样可以使事情变得更简单。

谢谢!最大 编辑Lyhan

Lyhan - 谢谢,但你的解决方案似乎不起作用。例如,在结果的第一行,使用您的方法,我有

| user_id | group_concat(pupils.id separator ",")                                                                         
|       1 | 2292   

但是,如果我以较慢,一步一步的方式获得相关的瞳孔ID,那么我会得到不同的结果:

select group_concat(user_group_teachers.user_group_id separator ",") 
from user_group_teachers 
where user_group_teachers.teacher_id = 1 
group by user_group_teachers.teacher_id;

我得到了

| group_concat(user_group_teachers.user_group_id separator ",")  
| 12,1033,2117,2280,2281   

将这些值(user_group ids)插入另一个查询:

select group_concat(user_group_members.pupil_id separator ",") 
from user_group_members 
where user_group_members.user_group_id in (12,1033,2117,2280,2281) 
group by user_group_members.user_group_id;

我得到了

| group_concat(user_group_members.pupil_id separator ",") 
| 47106,47107  

感谢group_concat方法btw,这很方便:)

2 个答案:

答案 0 :(得分:1)

我在上面做了几个对此解决方案很重要的评论,但我认为你可以从这两个查询开始,看看它是否足以让你得到你需要的东西。

要为所有群组的学生获取教师的有序列表,您可以这样做:

select distinct t.teacher_id, m.pupil_id
from user_groups g
    inner join user_group_teachers t
        on t.user_group_id = g.id
    inner join user_group_members m
        on t.user_group_id = g.id
order by t.teacher_id, m.pupil_id

要为有与小组关系的学生获取教师的有序列表,您可以这样做:

select g.id, t.teacher_id, m.pupil_id
from user_groups g
    inner join user_group_teachers t
        on t.user_group_id = g.id
    inner join user_group_members m
        on t.user_group_id = g.id
order by g.id, t.teacher_id, m.pupil_id

您必须遍历这些结果集并将它们转换为嵌套数组,但它是您想要的数据。

更新:更新:如果数据集太大或您不想走一个结果集,那么您可以这样做来模拟上面第一个查询的结果并构建您的基于查询结果集的子数组:

/* Use this query to drive the batch */
select distinct t.teacher_id
from user_groups_teachers t
order by t.teacher_id

/* Inside a loop based on first query result, pull out the array of pupils for a teacher */
select distinct m.pupil_id
from user_groups_members m
    inner join user_groups g
        on g.id = m.user_group_id
    inner join user_groups_teachers t
        on t.user_group_id = g.id
where t.teacher_id = /* parameter */
order by m.pupil_id

答案 1 :(得分:0)

这就是我提出的:

    select pupil_group_teachers.teacher_id, group_concat(pupil_group_members.pupil_id separator ',') 
    from pupil_group_teachers join pupil_groups on pupil_group_teachers.pupil_group_id = pupil_groups.id
    join pupil_group_members on pupil_group_members.pupil_group_id = pupil_groups.id
    group by pupil_group_teachers.teacher_id;
它似乎工作,而且非常快。 Lyhan(他已经删除了他的答案)和David Fleeman都帮助我解决了问题。干杯。

相关问题