MySQL中的复杂连接和MAX()查询

时间:2016-04-01 15:15:16

标签: mysql

我需要在4个表格中进行连接,同时选择与人员关联的最大(即最近)测试时间戳。对于班级中的每个学生,我想查找他们最近的测试是什么,并获取其ID和时间戳

SELECT students.ref, 
       students.fname, 
       students.sname, 
       classes.name AS 'group', 
       tests.id, 
       max(tests.timestamp)
FROM tests, students, classlinks, classes 
WHERE tests.ref=students.ref AND 
       classlinks.ref=students.ref AND 
       classlinks.classid=29 AND 
       tests.grade=2 AND 
       tests.subject=2 
GROUP BY students.ref
ORDER BY students.sname ASC, students.fname ASC

看起来就像它是完美的:对于班级中的每个学生,它给出了他们最近测试的时间戳。不幸的是,与该时间戳关联的测试ID是错误的:它只是给出了随机测试的测试ID。

如果我将'组更改为'是

GROUP BY students.ref, tests.id

然后查询匹配正确的测试ID以更正时间戳,但现在每个学生都有几个条目。有没有人有任何建议,以便我可以为每个学生获得一行,正确的测试ID匹配,以纠正最近的时间戳?任何帮助赞赏。感谢。

表格描述:

mysql> describe students;
+--------+-------------+------+-----+---------+----------------+
| Field  | Type        | Null | Key | Default | Extra          |
+--------+-------------+------+-----+---------+----------------+
| id     | int(11)     | NO   | PRI | NULL    | auto_increment |
| ref    | varchar(50) | NO   | UNI | NULL    |                |
| fname  | varchar(22) | NO   |     | NULL    |                |
| sname  | varchar(22) | NO   |     | NULL    |                |
| school | int(11)     | NO   |     | NULL    |                |
| year   | int(11)     | NO   |     | NULL    |                |
+--------+-------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
mysql> describe classes;
+---------+-------------+------+-----+---------+----------------+
| Field   | Type        | Null | Key | Default | Extra          |
+---------+-------------+------+-----+---------+----------------+
| id      | int(11)     | NO   | PRI | NULL    | auto_increment |
| subject | int(11)     | YES  | MUL | NULL    |                |
| type    | int(11)     | YES  |     | 1       |                |
| school  | int(11)     | YES  |     | NULL    |                |
| year    | int(11)     | YES  |     | NULL    |                |
| name    | varchar(50) | YES  |     | NULL    |                |
+---------+-------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)

mysql> describe classlinks;
+---------+-------------+------+-----+---------+----------------+
| Field   | Type        | Null | Key | Default | Extra          |
+---------+-------------+------+-----+---------+----------------+
| id      | int(11)     | NO   | PRI | NULL    | auto_increment |
| ref     | varchar(50) | YES  | MUL | NULL    |                |
| subject | int(11)     | YES  |     | NULL    |                |
| school  | int(11)     | YES  |     | NULL    |                |
| classid | int(11)     | YES  | MUL | NULL    |                |
| type    | int(11)     | YES  |     | 1       |                |
+---------+-------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
mysql> describe tests;
+------------+-------------+------+-----+-------------------+-----------------------------+
| Field      | Type        | Null | Key | Default           | Extra                       |
+------------+-------------+------+-----+-------------------+-----------------------------+
| id         | int(11)     | NO   | PRI | NULL              | auto_increment              |
| subject    | int(11)     | YES  |     | NULL              |                             |
| ref        | varchar(22) | NO   | MUL | NULL              |                             |
| test       | int(3)      | NO   |     | NULL              |                             |
| grade      | varchar(22) | NO   |     | NULL              |                             |
| timestamp  | timestamp   | NO   | MUL | CURRENT_TIMESTAMP |                             |
| lastupdate | timestamp   | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |

2 个答案:

答案 0 :(得分:1)

我假设(ref,timestamp)的组合在tests表中是唯一的。这是我的解决方案,但我没有任何样本数据来验证它。如果不正确,请发布样本数据,以便我可以对其进行测试。

<强>更新

以下是正在运行的更新查询,请检查sqlfiddle

SELECT students.ref, 
  students.fname, 
  students.sname, 
  classes.name AS 'group', 
  tests.id, 
  T.timestamp
FROM (select ref,max(timestamp) as timestamp from tests group by ref)as T
    natural join tests, students, classlinks, classes 
WHERE
 T.ref=students.ref AND 
 classlinks.ref=students.ref AND
 classlinks.classid=classes.id AND 
 classlinks.classid=29 AND 
 tests.grade=2 AND 
 tests.subject=2
ORDER BY students.sname ASC, students.fname ASC

答案 1 :(得分:0)

使用SQL中的逻辑,查询可以写成如下,不确定mySQL,但希望逻辑有效。

Select ref
      ,fname
      ,sname
      ,ID
      ,group
      ,Timestamp

From
    (select
        S.ref
        ,S.fname
        ,S.sname,
        ,T.id
        ,classes.name AS 'group'
        ,T.timestamp
        from
            tests T,students S, classlinks, classes
        Where
            T.ref=S.ref and
            T.grade=2 AND 
            classlinks.ref=students.ref AND 
            classlinks.classid=29 AND 
            classlinks.classid=classes.id AND
            T.subject=2 ) A

    inner join

    (SELECT tests.ref        
            ,max(tests.timestamp) 
     FROM 
         tests 
     group by
         tests.ref
    ) B
    on
      A.ref=b.ref and
      A.timestamp = b.timestamp