2010-05-05 2 views
1

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

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 
    ); 

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

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

+0

Пожалуйста, пост кода, который вы написали до сих пор. Люди обычно не любят просто писать свой код для вас. –

+0

У меня теперь предложение GROUP BY SELECT user_id, rank FROM rank WHERE FK_gamePoule =? GROUP BY user_id Но следующий шаг более сложные :-) – Derk

ответ

0

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

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

+0

спасибо, у меня есть еще один запрос ВЫБРАТЬ * ИЗ рейтинги г ГДЕ \t FK_gamePoule = 0 И r.insertDate = COALESCE ( (SELECT r2.insertDate ИЗ рейтинга r2 WHERE r.FK_user = r2.FK_user ORDER BY r2.insertDate DESC LIMIT 1 OFFSET 1), '2048-12-31 23:59:59') Но если ваша лучше я буду использовать его :-) – Derk

+0

@ Derk, вам удалось заставить ваш запрос работать? У меня еще не было времени смотреть на это дальше. – Tony

0

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

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')