2013-04-17 2 views
0

Я запускаю бэкэнд CodeIgniter для игры, в которой информация о пользователе и таблица рекордов сохраняются в базе данных. Каждый пользователь может только войти в рекорды с его личным преимуществом, так что есть только одна запись для пользователяINNER JOIN с положением во второй таблице

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

У меня возникли проблемы с выяснением того, как получить позицию в таблице рекордов.

Скажем, мои пользовательские таблицы выглядит следующим образом

user_table 
| id|name| 
|...| ...| 

highscore_table 
|id |user_id|points| 
|...| ... | ... | 

В SQL заявление, не включая позиции рекордов, выглядит следующим образом

SELECT user_table.id, name, points 
FROM user_table 
INNER JOIN highscore_table ON user_table.id = highscore_table.user_id 
ORDER BY name 

Экспортируемые данные должны выглядеть следующим образом

|id | name|points|hs_position| 
|...| ... | ... | ... | 

Обычно, когда я запрашиваю рекорды, я делаю что-то подобное, но сортирую данные по points. Это просто не вариант.

Может ли кто-нибудь сказать мне, как этого добиться, привести меня в правильном направлении или просто и просто сказать мне, что это невозможно?

Любая помощь очень ценится.

+3

Что такое СУБД? –

+0

Что вы пытаетесь сделать? – Duk

+0

Это SQLite? –

ответ

1

Если вы используете СУБД, которая не поддерживает функции ранжирования (например, SQLite), то один из способов достижения этой цели является с помощью подзапроса - например, так:

SELECT u.id, u.name, h.points, 
     (select count(*) + 1 
     from highscore_table h2 
     WHERE h2.points > h.points) hs_position 
FROM user_table u 
INNER JOIN highscore_table h ON u.id = h.user_id 
ORDER BY u.name 

SQLFiddle here.

(Если вы хотите густой-рейтинг высокого балла, изменить count(*) + 1 к count(distinct h2.points) + 1.)

2

У меня возникли проблемы с выяснением того, как получить позицию в таблице рекордов .

Если вы используете SQL-сервер можно использовать DENSE_RANK для HS-Rank и ROW_NUMBER, чтобы получить строку с самой высокой точкой на пользователя:

WITH cte 
    AS (SELECT user_table.id, 
       name, 
       points, 
       hs_position=Dense_rank() 
           OVER( 
           ORDER BY points DESC), 
       Personalbest_Num=Row_number() 
            OVER( 
            partition BY id 
            ORDER BY points DESC) 
     FROM user_table 
       INNER JOIN highscore_table 
         ON user_table.id = highscore_table.user_id) 
SELECT id, 
     name, 
     points, 
     hs_position 
FROM cte 
WHERE personalbest_num = 1 
ORDER BY hs_position ASC, 
      name ASC 
0

Это решение для MySQL:

SELECT user_table.id, name, points, hs_table.rank 
FROM user_table 
INNER JOIN 
(
    SELECT hs.*, IF(@prev != points, @pos:[email protected] + 1, @pos) as rank 
    , @prev:=points 
    FROM highscore_table hs, 
     (SELECT @pos:=0, @prev:=NULL) vars 
    ORDER BY points DESC 
) hs_table 
ON user_table.id = hs_table.user_id 
ORDER BY name 

Люди с одинаковым количеством пунктов будут иметь одинаковую ранг.

Смежные вопросы