Показать сетку рейтинга для игры: оптимизация левого внешнего соединения и поиск игрока

Я хочу сделать рейтинговую сетку.

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

Таблица SimpleValue: ключ varchar, значение int, playerId int

У меня есть плеер, у которого есть несколько SimpleValue.

Table Player: id int, никнейм varchar

А теперь представьте эти записи:

Простое значение:

Key      value     playerId
for      1         1
int      2         1
agi      2         1
lvl      5         1

for      6         2
int      3         2
agi      1         2
lvl      4         2

Игрок:

id     nickname
1      Bob
2      John

Я хочу отображать ранг этих игроков на различных SimpleValue. Что-то типа:

nickname      for       lvl     
Bob           1         5       
John          6         4  

На данный момент я генерирую SQL-запрос на основе того, какой ключ SimpleValue вы хотите отобразить, и по какому ключу SimpleValue вы хотите заказать игроков.

например: я хочу отображать «lvl» и «for» каждого игрока и упорядочивать их на «lvl»

Сгенерированный запрос:

SELECT p.nickname as nickname, v1.value as lvl, v2.value as for
FROM Player p
LEFT OUTER JOIN SimpleValue v1 ON p.id=v1.playerId and v1.key = 'lvl'
LEFT OUTER JOIN SimpleValue v2 ON p.id=v2.playerId and v2.key = 'for'
ORDER BY v1.value

Этот запрос работает отлично. НО, если я хочу отобразить 10 разных значений, он генерирует 10 «левых внешних соединений». Есть ли способ упростить этот запрос?

У меня есть второй вопрос: есть ли способ отобразить часть этого рейтинга. Представьте, что у меня 1000 игроков, и я хочу отобразить ТОП-10, я использую ключевое слово LIMIT. Теперь я хочу отобразить ранг игрока Боба, который составляет 326/1000, и я хочу отобразить 5-рангового игрока выше и ниже (то есть от 321 до 331 позиции). Как я могу достичь этого?

Спасибо.


person Jerome Cance    schedule 23.04.2010    source источник
comment
вы получаете гибкость со схемой атрибутов объекта, но это приводит к трудностям при записи и оптимизации запросов. Эти запросы были бы просты с фиксированной схемой таблицы (где атрибуты — это просто столбцы в таблице, а не строки).   -  person KM.    schedule 23.04.2010


Ответы (1)


Это называется «перекрестный запрос». Вы можете использовать операторы условной суммы, подобные этой странице.

Получить:

SELECT p.nickname as nickname
, SUM(IF(key = "for", value,0)) AS `for`
, SUM(IF(key = "int", value,0)) AS `int`
, SUM(IF(key = "agi", value,0)) AS `agi`
, SUM(IF(key = "lvl", value,0)) AS `lvl`
FROM Player p
LEFT OUTER JOIN SimpleValue v1 ON p.id=v1.playerId
GROUP By p.nickname
ORDER BY v1.value
person Dan    schedule 23.04.2010
comment
Разве вы не хотели бы добавить GROUP BY, чтобы сделать результаты запроса значимыми? - person KM.; 23.04.2010
comment
Да, я заметил это после того, как выложил это. Спасибо хоть. - person Dan; 23.04.2010