2012-03-03 2 views
0

Я Вычисляя MIN, MAX и AVG уровня игрока:расчеты MySQL со значениями

SELECT 
    MIN(`p`.`level`) AS 'min', 
    MAX(`p`.`level`) AS 'max', 
    AVG(`p`.`level`) AS 'avg' 
FROM `dfh`.`players` `p` 

Как как я могу получить значение p.name поля, которое относится к MIN и MAX?

Fe. Я получил эти значения в моей p таблицы:

Lp. | Name | Level 
1 | Test | 12 
2 | Tesx | 15 
3 | Anot | 150 

И запрос выведет следующее:

MIN: 12 
MAX: 150 

Но я хочу, чтобы вывести также Name соответствующую MIN и MAX значения по:

MIN: 12 Test 
MAX: 150 Anot 

Как я могу это сделать?

+0

MySQL не имеет К сожалению, аналитических функций, так что вы должны будете написать длинный и скучный запрос. – Benoit

+0

@Benoit Большая цепочка 'UNION' скучна? –

+0

@ Майкл: :) Я должен объяснить, что такое скучно. Для меня любой код, который потребует высокой дозы Copy-paste, несколько скучен. В этих союзах меняется только совокупная функция! – Benoit

ответ

2

Попробуйте этот запрос -

SELECT 'MIN' property, GROUP_CONCAT(p1.name) name, p1.level FROM players p1 
    JOIN (SELECT MIN(level) level FROM players) p2 
    ON p1.level = p2.level 
UNION 
SELECT 'MAX' property, GROUP_CONCAT(p1.name) name, p1.level FROM players p1 
    JOIN (SELECT MAX(level) level FROM players) p2 
    ON p1.level = p2.level 

запроса с наивысшим значением «опыт» и любой «идентификатор» -

SELECT * FROM 

    (SELECT 'MIN' property, p1.id, p1.level, p1.name FROM players p1 
    JOIN (
     SELECT 
     level, MAX(experience) experience 
     FROM 
     players, 
     (SELECT @level:=MIN(level) FROM players) t 
     WHERE level = @level 
    ) p2 
    ON p1.experience = p2.experience AND p1.level = p2.level 
    ORDER BY id LIMIT 1) t_min 

UNION 

SELECT * FROM 

    (SELECT 'MAX' property, p1.id, p1.level, p1.name FROM players p1 
    JOIN (
     SELECT 
     level, MAX(experience) experience 
     FROM 
     players, 
     (SELECT @level:=MAX(level) FROM players) t 
     WHERE level = @level 
    ) p2 
    ON p1.experience = p2.experience AND p1.level = p2.level 
    ORDER BY id LIMIT 1) t_max 

Используйте этот набор данных в качестве подзапроса для соединения с другой таблицей -

SELECT * FROM 
(
    SELECT * FROM 

    (SELECT 'MIN' property, p1.id, p1.level, p1.name FROM players p1 
     JOIN (
     SELECT 
      level, MAX(experience) experience 
     FROM 
      players, 
      (SELECT @level:=MIN(level) FROM players) t 
     WHERE level = @level 
    ) p2 
     ON p1.experience = p2.experience AND p1.level = p2.level 
    ORDER BY id LIMIT 1) t_min 

    UNION 

    SELECT * FROM 

    (SELECT 'MAX' property, p1.id, p1.level, p1.name FROM players p1 
     JOIN (
     SELECT 
      level, MAX(experience) experience 
     FROM 
      players, 
      (SELECT @level:=MAX(level) FROM players) t 
     WHERE level = @level 
    ) p2 
     ON p1.experience = p2.experience AND p1.level = p2.level 
    ORDER BY id LIMIT 1) t_max 
) p 
LEFT JOIN guild_member gm 
    ON gm.id = p.id 
+0

Он отлично работает, но что, если есть два игрока с одинаковым уровнем? Он должен выбрать один из них в этом случае, атм. он выбирает всех игроков с одинаковым уровнем. – Cyclone

+0

Какой из них должен быть выбран? – Devart

+0

Ну, есть поле «опыт», поэтому, возможно, если есть два игрока (или более) с одинаковым уровнем, мы должны выбрать тот, который имеет поле «опыт» (что-то вроде «ORDER BY p.experience DESC»). – Cyclone

1

Это вернет низкие/высокие имена эффективно:

select 'MIN', level, name from players order by level limit 1 
union all 
select 'MAX', level, name from players order by level desc limit 1 

Обратите внимание на отсутствие подзапросов ...

+0

[Err] 1221 - Неправильное использование UNION и ORDER BY – Cyclone

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