Postgres Group By - расчет коэффициента на пользователя - PullRequest
0 голосов
/ 23 мая 2018

У меня есть таблица ставок и один столбец с названием «Статус», который указывает, является ли он «Правильным» или «Неверным».Я могу вычислить коэффициент для конкретного пользователя следующим образом:

SELECT 
    (SELECT COUNT(*) FROM bets_bet WHERE user_id = 1 AND status = 'Correct')::DECIMAL AS correct_guesses,
    (SELECT COUNT(*) FROM bets_bet WHERE user_id = 1 AND status = 'Incorrect')::DECIMAL AS incorrect_guesses,
    CAST((SELECT COUNT(*) FROM bets_bet WHERE user_id = 1 AND status = 'Correct') AS DECIMAL) / CAST((SELECT COUNT(*) FROM bets_bet WHERE user_id = 1 AND status = 'Incorrect') AS DECIMAL) AS Ratio;

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

SELECT
    user_id, accounts_usuario.username, 
    (SELECT COUNT (*) FROM bets_bet WHERE status = 'Correct') AS Corrects,
    (SELECT COUNT (*) FROM bets_bet WHERE status = 'Incorrect') AS Incorrects,
    (SELECT COUNT (*) FROM bets_bet WHERE status = 'Pending') AS Pending,
    --CAST(COUNT(*) AS DECIMAL) / CAST((SELECT COUNT(*) FROM bets_bet) AS DECIMAL) AS Ratio
    CAST((SELECT COUNT(*) FROM bets_bet WHERE status = 'Correct') AS DECIMAL) / CAST((SELECT COUNT(*) FROM bets_bet WHERE status = 'Incorrect') AS DECIMAL) AS Ratio
FROM bets_bet
LEFT JOIN accounts_usuario ON bets_bet.user_id = accounts_usuario.id
GROUP BY user_id, accounts_usuario.username
ORDER BY Ratio, Corrects;

enter image description here

Как мне достичь желаемого результата?

Обновление

У меня такое жепроблема после реализации следующей логики:

Я создал класс SeasonalUser для хранения ставок каждого года, а поле user - это внешний ключ для идентификатора класса User.Так что теперь у меня та же логика, но с 3 таблицами, и я снова получаю одно и то же значение для каждого поля.

-- Calculate the accuracy ratio for every SeasonUser
SELECT
    bet.user_id, usr.username, 
    COUNT(CASE WHEN  status = 'Correct'   THEN  1 END) AS Corrects, 
    COUNT(CASE WHEN  status = 'Incorrect' THEN  1 END) AS Incorrects, 
    COUNT(CASE WHEN  status = 'Pending'   THEN  1 END) AS Pending,    

    CAST(COUNT(CASE WHEN  status = 'Correct' THEN  1 END) AS DECIMAL) / CAST(COUNT(CASE WHEN status = 'Incorrect' THEN 1 END) AS DECIMAL) AS Ratio

FROM bets_bet AS bet
LEFT JOIN accounts_seasonusuario AS s_usr ON bet.user_id = s_usr.id
LEFT JOIN accounts_usuario AS usr ON usr.id = s_usr.user_id
GROUP BY bet.user_id, s_usr.id, usr.username
ORDER BY Ratio DESC, Corrects DESC;

Я не хочу группировать по usr.username (пользовательский глобальный), потому чтоЯ хочу соотношение в год, но, похоже, оно обязательно, если я хочу напечатать реальное имя пользователя в возвращаемой таблице usr.username.

Чего мне не хватает?

1 Ответ

0 голосов
/ 23 мая 2018

SQL 1:

SELECT
    user_id, accounts_usuario.username, 
    (SELECT COUNT (*) FROM bets_bet t2 WHERE t1.user_id = t2.user_id and status = 'Correct') AS Corrects,
    (SELECT COUNT (*) FROM bets_bet t2 WHERE t1.user_id = t2.user_id and status = 'Incorrect') AS Incorrects,
    (SELECT COUNT (*) FROM bets_bet t2 WHERE t1.user_id = t2.user_id and  status = 'Pending') AS Pending,
    --CAST(COUNT(*) AS DECIMAL) / CAST((SELECT COUNT(*) FROM bets_bet) AS DECIMAL) AS Ratio
    CAST((SELECT COUNT(*) FROM bets_bet t2 WHERE t1.user_id = t2.user_id and  status = 'Correct') AS DECIMAL) / CAST((SELECT COUNT(*) FROM bets_bet t2 WHERE t1.user_id = t2.user_id and  status = 'Incorrect') AS DECIMAL) AS Ratio
FROM bets_bet t1 
LEFT JOIN accounts_usuario ON bets_bet.user_id = accounts_usuario.id
GROUP BY user_id, accounts_usuario.username
ORDER BY Ratio, Corrects;

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

SQL 2:

SELECT
    user_id, accounts_usuario.username, 
    count(case when  status = 'Correct' then  1 end ), 
    count(case when  status = 'Incorrect' then  1 end ), 
    count(case when  status = 'Pending' then  1 end ),    
    --CAST(COUNT(*) AS DECIMAL) / CAST((SELECT COUNT(*) FROM bets_bet) AS DECIMAL) AS Ratio
    count(case when  status = 'Correct' then  1 end ) / count(case when  status = 'Incorrect' then  1 end ) AS Ratio
FROM bets_bet t1 
LEFT JOIN accounts_usuario ON bets_bet.user_id = accounts_usuario.id
GROUP BY user_id, accounts_usuario.username
ORDER BY Ratio, Corrects;

Вы можете просто посчитать статус, как показано в запросе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...