【问题标题】:Self join to get common students for a list of teachers自加入获取普通学生获取教师名单
【发布时间】:2019-08-15 10:54:43
【问题描述】:

我正在使用 Express.js 在 Node.js 中编写后端 API。

在其中一个 API 中,我需要返回给定教师列表共有的学生列表。

例如,如果

  • Teacher1 教 Tom、Jerry 和 Ed。
  • Teacher2 教 Ed、Eddy 和 Jerry。
  • Teacher3 教 Ed、Edd 和 Eddy。

API 接受教师列表[Teacher1, Teacher2, Teacher3] 的输入。那么输出应该是[Ed],因为它是三位老师之间唯一的共同学生。

这是定义教师和学生之间关联的寄存器表。

id | teacher_email    | student_email       | valid |
41 | Tom@gmail.com    | May@gmail.com       |     1 |
42 | Tom@gmail.com    | jerry@gmail.com     |     1 |
43 | Tom@gmail.com    | Kestov@gmail.com    |     1 |
44 | Toni@gmail.com   | hdjh@kd.com         |     1 |
58 | larry@gmail.com  | jerry@gmail.com     |     1 |
59 | gerrad@gmail.com | jerry@gmail.com     |     1 |
60 | gerrad@gmail.com | Kestov@gmail.com    |     1 |
61 | gerrad@gmail.com | Katrin@gmail.com    |     1 |
62 | gerrad@gmail.com | Piniyara@gniail.com |     1 |
63 | gerrad@gmail.com | Ritz@gmail.com      |     1 |
64 | gerrad@gmail.com | Taz@gmail.com       |     1 |
65 | gerrad@gmail.com | Fensuk@gmail.com    |     1 |
66 | gerrad@gmail.com | Joe@gmail.com       |     1 |
67 | gerrad@gmail.com | Mustafa@gmail.com   |     1 |
69 | Tom@gmail.com    | Fensuk@gmail.com    |     1 |
70 | Tom@gmail.com    | Taz@gmail.com       |     1 |

我尝试编写一个自联接查询,但它为输入中的所有教师分配了所有学生。这里是:

  const commonStudentsForTeachersQueryString = "SELECT a.student_email "+
  "FROM register a, register b "+
  "WHERE b.teacher_email=a.teacher_email "+
  "AND "+
  "a.teacher_email in (?) "+
  "AND "+
  "a.valid=? "+
  "GROUP BY a.student_email";

虽然,可以选择让每个老师的所有学生循环并Intersecting 他们在那里,但这不是最佳选择。我只想使用一个查询来获取教师列表中的普通学生。

Here 是供参考的 GitHub 存储库。

【问题讨论】:

    标签: mysql sql node.js join


    【解决方案1】:

    您可以为此目的使用聚合和having

    select r.student_email
    from register r
    where r.teacher_email in (?, ?, ?)
    group by r.student_email
    having count(distinct teacher_email) = 3;
    

    count(distinct) 是因为 - 至少在理论上 - 一个学生可以在两个不同的班级有同一个老师。

    3 是需要匹配的教师人数。

    编辑:

    另一种方法使用intersect

    select r.student_email
    from registrations r
    where r.teacher_email = ?
    intersect
    select r.student_email
    from registrations r
    where r.teacher_email = ?
    intersect
    select r.student_email
    from registrations r
    where r.teacher_email = ?;
    

    【讨论】:

    • 嘿@Gordon,谢谢。我试过这个查询,我得到了所有不常见的学生。与期望的结果完全相反。
    • @HarshVardhan 。 . .你误解了结果。此查询无法返回三者中常见的学生。
    • 我又检查了一遍..你可以在这里看到结果。 imgur.com/a/OELoGXv
    • 我尝试了 intersect 查询,但我得到了一个 ER_PARSE_ERROR:collabedit.com/gagmm
    • 嘿@Gordon,刚刚知道我们不能在 MySQL 中使用 INTERSECT。
    【解决方案2】:

    这个查询有效:

    SELECT a.student_email FROM register a JOIN register b ON a.teacher_email = b.teacher_email WHERE a.teacher_email IN (?) And a.valid=1 GROUP BY a.student_email HAVING COUNT(DISTINCT a.teacher_email)=?
    

    前一个参数是 教师的电子邮件 ID,它的 size 是后者。

    【讨论】:

      猜你喜欢
      • 2023-01-28
      • 2019-07-22
      • 1970-01-01
      • 1970-01-01
      • 2020-08-19
      • 2016-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多