Postgres Group By - 每位用户的比率计算

时间:2018-05-23 11:48:44

标签: postgresql group-by

我有一个投注表和一个名为“状态”的列。这表明它是否正确'或者'不正确'。我可以将特定用户的比率计算为:

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类来存储每年的赌注,而field字段用户是User类id的外键。所以现在我有相同的逻辑,但有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(用户全局)进行分组,因为我想要每年的比例,但如果我想在返回的表格中打印真实的用户名,它看起来是强制性的{ {1}}。

我错过了什么?

1 个答案:

答案 0 :(得分:1)

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;

它将为所有行返回相同的结果,因为您没有指定应该生成哪个用户ID结果。为了这个添加条件,如上所示。

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;

您可以简单地计算查询中显示的状态。