MySQL выбор записи с последней датой - PullRequest
2 голосов
/ 21 января 2012

У меня есть две таблицы: КУРСЫ и РАЗРЕШЕНИЯ.Я пытаюсь сделать 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 ]

2 голосов
/ 21 января 2012

Вам нужно использовать 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)

(было бы проще со структурами таблиц)

Другая возможность - думать об обратном.Присоединитесь к таблице РАЗРЕШЕНИЯ на себя и найдите разрешение, которое не имеет более высокой отметки времени

   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))
0 голосов
/ 21 января 2012
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'

В зависимости от размера ваших данных вы можете подумать о добавлении индекса (C_ID, TS) для таблицы PERMISSIONS, чтобы ускорить поиск последней даты:

ALTER TABLE `PERMISSIONS` ADD INDEX (`C_ID`,`TS`);
0 голосов
/ 21 января 2012

Другая альтернатива - с помощью подвыбора, вычисляющего максимальные временные метки таблицы разрешений:

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'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...