MySQL查找匹配多个轴行的条目

时间:2016-07-06 19:16:25

标签: mysql join

我有一个包含3个常规表和2个链接表的模式,如下所示:

tutorial
  id

exam
  id

user
  id

exam_user
  user
  exam

tutorial_user
  user
  tutorial

链接表确定哪些用户参加了哪个考试/教程。 从考试ID开始,我试图找到其成员参加考试的教程。

例如:

exam_user
+----+-------+----------+
| id | exam  | user     |
+----+-------+----------+
| 23 |     8 |        1 |
| 24 |     8 |        5 |
| 25 |     8 |        8 |
| 26 |     8 |       11 |
| 27 |     8 |       12 |
+----+-------+----------+

tutorial_user
+----+----------+----------+
| id | tutorial | user     |
+----+----------+-----------
| 56 |        2 |        1 |
| 57 |        2 |        5 |
| 58 |        2 |        8 |
| 59 |        2 |       11 |
+----+----------+----------+
+----+----------+----------+
| id | tutorial | user     |
+----+----------+-----------
| 60 |        3 |        1 |
| 61 |        3 |        5 |
| 62 |        3 |        8 |
| 63 |        3 |       15 |
+----+----------+----------+

教程2会匹配,因为所有条目都在考试8中,但教程3不会,因为用户11不在。

有没有(相对)有效的方法来实现上述目标?

1 个答案:

答案 0 :(得分:0)

你怎么样尝试这样的事情:

select * from tutorial_user where tutorial not in
(
    select tutorial from
    (
        (
        select ex.exam, ex.user as ex_user, tut.tutorial as tutorial, 
        tut.user as tut_user from exam_user ex
        inner join tutorial_user tut on 
        ex.User = tut.User
        )
        union all
        (
        select null, null, tutorial, user as tut_user from tutorial_user
        )
    ) src
    group by tutorial, tut_user
    having count(tut_user) = 1
)

现在第一个查询应该给你一个看起来像这样的列表(基本上是每个用户的考试和教程的组合):

+----+-------+----------+-------------+---------+
| id | exam  | user     | Tutorial    | User    |
+----+-------+----------+-------------+---------+
| 23 |     8 |        1 | 2           | 1       |
| 23 |     8 |        1 | 3           | 1       |
| 24 |     8 |        5 | 2           | 5       |
| 24 |     8 |        5 | 3           | 5       |
...

接下来,通过对下一个查询进行联合,你最终会得到这样的结果:

+-----+-------+----------+-------------+---------+
| id  | exam  | user     | Tutorial    | User    |
+-----+-------+----------+-------------+---------+
| 23  |     8 |        1 | 2           | 1       |
| 23  |     8 |        1 | 3           | 1       |
| 24  |     8 |        5 | 2           | 5       |
| 24  |     8 |        5 | 3           | 5       |
| null| null  | null     | 2           | 1       |
| null| null  | null     | 2           | 5       |
| null| null  | null     | 2           | 8       |
...

基本上,这使我们能够做的是一个分组声明,它将突出显示教程表中的用户,而不是检查表中的用户。所述重点将与having()子句一起使用。如果计数为1,那么教程表中的某个人不在考试表中。你现在要做的就是从教程表中选择不属于你所发现的教程的教程,你应该做得很好。