2016-11-29 2 views
0

У меня есть таблица jackpot с колонками uid для ID пользователя и nright для получения нескольких правильных ответов.Вычисление балла по рангу позиции

У меня есть возможность выбирать и оценивать пользователей по правильным ответам, но что дальше?

SELECT 
    a1.uid, 
    a1.nright, 
    COUNT(a2.nright) AS rank 
FROM 
    jackpot a1, 
    jackpot a2 
WHERE 
    a1.nright < a2.nright 
OR (
    a1.nright = a2.nright 
    AND a1.uid = a2.uid 
) 
GROUP BY 
    a1.uid, 
    a1.nright 
ORDER BY 
    a1.nright DESC, 
    a1.uid DESC 

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

Только пользователи с топ-3 MAX nright получают баллы.

Общее количество баллов = количество пользователей * 20.

Первая позиция получает 70% от общей суммы, 2 - 20%, 3 - 10%.

В случае равных правильных ответов между пользователями точки распределяются равномерно (50/50, 33/33/33 ...).

SQL Fiddle

+0

Было бы очень полезно, если вы после DML и DDL вашего SQL, а также, если вы делаете [SQL Fiddle] (http://sqlfiddle.com) –

ответ

2

Вы должны разлагаться, что вы хотите.

1-й шаг: Вы хотите получить 3 лучших результата.

SELECT nright 
FROM jackpot 
ORDER BY nright DESC 
LIMIT 3 

второй шаг: идентификатору пользователя, который получает это первые 3 баллов

SELECT j.uid 
FROM jackpot j 
INNER JOIN (
    SELECT nright 
    FROM jackpot 
    ORDER BY nright DESC 
    LIMIT 3) AS t ON t.nright = j.nright 

третий шаг: общее количество точки

SELECT COUNT(uid)*20 AS lot FROM jackpot 

четвёртую шаг: ранг и число лиц

Здесь мы должны использовать переменную, так как вы находитесь в php, вы не можете использовать set @var:= X;, поэтому трюк состоит в том, чтобы сделать Select @var:= X, эта переменная не будет работать из-за агрегатных функций. Так что вам нужно сделать, это:

SELECT @rank := @rank+1 as rank,T1.nright,T1.nb,T1.lot 
FROM(
    SELECT nright, 
      COUNT(uid) as nb, 
     (SELECT COUNT(uid)*20 FROM jackpot) as lot 
    FROM jackpot 
    GROUP BY nright 
    ORDER BY nright DESC 
    LIMIT 3 
    )T1, (SELECT @rank:= 0) r 

пятый шаг: Распределение лотов

SELECT j.uid, 
    CASE 
    WHEN t.rank = 1 THEN (t.lot*0.7)/t.nb 
    WHEN t.rank = 2 THEN (t.lot*0.2)/t.nb 
    WHEN t.rank = 3 THEN (t.lot*0.1)/t.nb 
    END as lot 

FROM jackpot j 
INNER JOIN 
(SELECT @rank := @rank+1 as rank,T1.nright,T1.nb,T1.lot 
FROM(
    SELECT nright, 
      COUNT(uid) as nb, 
     (SELECT COUNT(uid)*20 FROM jackpot) as lot 
    FROM jackpot 
    GROUP BY nright 
    ORDER BY nright DESC 
    LIMIT 3 
    )T1, (SELECT @rank:= 0) r) t ON t.nright = j.nright 
+0

Спасибо за объяснение, но я получаю следующую ошибку: У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с '@rank: = 0) r GROUP BY nright, rank ORDER BY nright DESC LIMIT 3) AS' в строке 10 – user1542894

+0

Hm, не должен j. uid и j.nright быть jackpot.uid и jackpot.nright? Потому что в противном случае он говорит: «В таблице нет такого столбца». Я попытался изменить его, но получил ошибку: «Операнд должен содержать 1 столбец» – user1542894

+0

Да, извините. Вот почему я не должен публиковать какие-либо записи с моего рабочего места. : D –