SQL-запрос: последний, но один ранг для пользователя - PullRequest
1 голос
/ 05 мая 2010

Моя структура таблицы выглядит следующим образом:

create table rankings (
    id IDENTITY NOT NULL,
    user_id INT NOT NULL,
    game_poule_id INT NOT NULL,
    rank INT NOT NULL,
    insertDate DATETIME NOT NULL,
    FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
    FOREIGN KEY (game_poule_id) REFERENCES game_poules(id) ON DELETE CASCADE
    );

Все старые рейтинги пользователей для игры сохраняются в этой таблице. Теперь я хочу иметь последнее, но одно место в таблице для всех пользователей геймпулы.

Кто-нибудь знает, как этого добиться? Спасибо

Ответы [ 2 ]

0 голосов
/ 05 мая 2010

Другое возможное (не очень хорошее) решение

SELECT
  *
FROM
  rankings r
WHERE
    FK_gamePoule = 0 AND
  r.insertDate = COALESCE(
    (SELECT
       r2.insertDate
     FROM
       rankings r2
     WHERE
       r.FK_user = r2.FK_user ORDER BY r2.insertDate DESC
     LIMIT 1
     OFFSET 1), '2048-12-31 23:59:59')
0 голосов
/ 05 мая 2010

Вам нужно самостоятельно присоединиться к таблице, чтобы получить нужные вам записи. Для этого ответа я создал вашу таблицу без внешних ключей, поскольку они не требуются для его работы.

CREATE TABLE Rankings (
    id int IDENTITY NOT NULL,
    user_id INT NOT NULL,
    game_poule_id INT NOT NULL,
    rank INT NOT NULL,
    insertDate DATETIME NOT NULL
    );

Вставьте пример данных. Без дополнительной информации я не смогу имитировать лучше, чем эта.

INSERT Rankings(user_id,game_poule_id,rank,insertDate)
VALUES(1, 100, 3, CURRENT_TIMESTAMP-2)
INSERT Rankings(user_id,game_poule_id,rank,insertDate)
VALUES(1, 100, 2, CURRENT_TIMESTAMP-1)
INSERT Rankings(user_id,game_poule_id,rank,insertDate)
VALUES(1, 101, 6, CURRENT_TIMESTAMP)
INSERT Rankings(user_id,game_poule_id,rank,insertDate)
VALUES(2, 100, 5, CURRENT_TIMESTAMP-2)
INSERT Rankings(user_id,game_poule_id,rank,insertDate)
VALUES(2, 100, 1, CURRENT_TIMESTAMP-1)
INSERT Rankings(user_id,game_poule_id,rank,insertDate)
VALUES(2, 101, 2, CURRENT_TIMESTAMP)

Запрос последнего, но одного ранга

SELECT Rankings.game_poule_id, Rankings.user_id, rank, MAX(Rankings.insertDate)
FROM Rankings INNER JOIN 
    (SELECT game_poule_id, user_id, MAX(insertDate) max_insert_date 
        FROM rankings 
        GROUP BY game_poule_id, user_id) Max_Ranking_Date
ON Rankings.user_id = Max_Ranking_Date.user_id
    AND Rankings.insertDate < Max_Ranking_Date.max_insert_date
    AND Rankings.game_poule_id = Max_Ranking_Date.game_poule_id
GROUP BY Rankings.game_poule_id, Rankings.user_id, rank 

ОБРАТИТЕ ВНИМАНИЕ! Как видно из результатов, вы не получите рейтинг для игры, в которой есть только одна строка на пользователя. Но поскольку вы запрашиваете «последнее, но одно», это имеет смысл только для игр с несколькими записями.

EDIT: Я только что понял, что запрос, который я предоставил, не будет возвращать по одной строке на пользователя на игру. Кто-нибудь хочет это исправить? Я должен продолжить работу :))

...