MySQL选择最新日期的记录

时间:2012-01-20 23:01:24

标签: mysql sql select join

我有两张桌子:COURSES和PERMISSIONS。我正在尝试在给定帐户中显示给定学生的所有现有课程的最新权限值SELECT

现在,我这样做:

SELECT COURSES.NAME, PERMISSIONS.VALUE, PERMISSIONS.TS
FROM COURSES LEFT JOIN PERMISSIONS
ON PERMISSIONS.C_ID = COURSES.C_ID AND PERMISSIONS.S_ID = '12345'
WHERE COURSES.A_ID = 'ABCDE'

我得到的结果是

NAME          |  VALUE  |   TS
-----------------------------------------------
Mathematics   | 1       | 2012-01-19 19:13:21
Mathematics   | 0       | 2012-01-19 19:13:15
Mathematics   | 0       | 2012-01-19 19:20:19
Mathematics   | 0       | 2012-01-19 19:20:27
Mathematics   | 0       | 2012-01-19 19:21:29
Biology       |         | 

我需要的是只显示带有最新时间戳(TS)的记录,以便显示:

NAME          |  VALUE  |   TS
-----------------------------------------------
Mathematics   | 0       | 2012-01-19 19:21:29
Biology       |         | 

我在课程名称上尝试GROUP BY并在时间戳上加上ORDER BY,但它没有找到正确的记录。

有人可以帮忙吗?

3 个答案:

答案 0 :(得分:2)

你需要使用HAVING。所以它应该是这样的

SELECT COURSES.NAME, PERMISSIONS.VALUE, PERMISSIONS.TS
FROM COURSES LEFT JOIN PERMISSIONS
ON PERMISSIONS.C_ID = COURSES.C_ID AND PERMISSIONS.S_ID = '12345'
WHERE COURSES.A_ID = 'ABCDE'
GROUP BY COURSES.A_ID
HAVING PERMISSIONS.TS = MAX(PERMISSIONS.TS)

(使用表格结构会更容易)

另一种可能性是以相反的方式思考。加入PERMISSIONS表,找到没有更高时间戳的权限

   SELECT COURSES.NAME, PA.VALUE, PA.TS
    FROM COURSES LEFT JOIN PERMISSIONS PA
    ON PA.C_ID = COURSES.C_ID AND PA.S_ID = '12345'
    WHERE COURSES.A_ID = 'ABCDE' 
        AND (PA.C_ID == NULL || NOT EXISTS (
            SELECT * 
            FROM PERMISSIONS PB
            WHERE PA.C_ID = PB.C_ID AND PB.S_ID = '12345' AND PB.TS > PA.TS))

答案 1 :(得分:0)

另一种选择 - 使用子选择计算权限表的最大时间戳:

SELECT courses.name, x.value, x.timestamp
FROM courses 
LEFT JOIN (SELECT p1.c_id, p1.s_id, p1.value, p1.timestamp
    FROM permissions p1 
    LEFT JOIN permissions p2 ON p1.c_id = p2.c_id AND p1.s_id = p2.s_id AND p1.timestamp < p2.timestamp
    WHERE p2.timestamp IS NULL) x ON courses.c_id = x.c_id AND x.s_id = '12345'
WHERE courses.a_id = 'ABCDE'

答案 2 :(得分:0)

SELECT COURSES.NAME, PL.VALUE, PL.TS
FROM COURSES
LEFT JOIN 
  ( SELECT 
       PERMISSIONS.C_ID, PERMISSIONS.VALUE, PERMISSIONS.TS
    FROM PERMISSIONS
    JOIN
      ( SELECT P.C_ID, MAX(P.TS) AS LATEST
        FROM PERMISSIONS P
        WHERE P.S_ID = '12345'
        GROUP BY P.C_ID ) PG
    ON PERMISSIONS.TS = PG.LATEST ) PL
  ON PL.C_ID = COURSES.C_ID
WHERE COURSES.A_ID = 'ABCDE'

根据您的数据大小,您可以考虑在PERMISSIONS表的(C_ID,TS)上添加索引,以加快查找最新日期:

ALTER TABLE `PERMISSIONS` ADD INDEX (`C_ID`,`TS`);