2015-12-15 57 views
1

我有一张表格,列出了每部电影和评论家的评分,评论家给那部电影的评分:(film_id,critic_id,score)。我有以下PostgreSQL的查询找到了10部电影有跨越批评的定数组中的最高平均分:PostgreSQL根据用户输入计算加权平均值

SELECT 
    f_id, avg(f_score) 
FROM 
    (
     SELECT 
      s.film_id as f_id, s.critic_id as c_id, s.score as f_score 
     FROM 
      score s 
     WHERE 
      s.critic_id = ANY(ARRAY['CRITIC_BOB_0213', 'CRITIC_AMY_9671']) 
     GROUP BY 
      s.film_id, s.critic_id, s.score 
    ) 
sub 
GROUP BY 
    f_id 
ORDER BY 
    avg desc 
LIMIT 
    10; 

在这种情况下,用户会说,他想知道评论家鲍勃和分数艾米,它返回:

f_id  | avg 
"742545" 13.0330650266333 
"220176" 6.7783259974 
"662682" 6.52305498088333 
... 

现在,我希望用户能够给某个评论者一定的权重。 因此基本上,用户输入[('CRITIC_BOB_0213', 0.923), ('CRITIC_AMY_9671', 0.212)](例如,如果他比Bob更重视Amy的判断),我需要查询来反映这一点。所以你会得到一个加权平均值:avg(score_bob*0.923 + score_amy*0.212)。我需要它在查询本身中,电影的数量是数百万,我不想在计算我的后端代码中的加权平均值之前将它们全部归还。

这在PostgreSQL中可能吗?

回答

0

这样做解决了它自己:

SELECT 
    f_id, avg(weighted_score) 
FROM 
    (
     SELECT 
      s.film_id as f_id 
     , 
     CASE 
      WHEN s.critic_id='CRITIC_BOB_0213' THEN s.score*CRITIC_BOB_WEIGHT 
      WHEN s.critic_id='CRITIC_AMY_9671' THEN s.score*CRITIC_AMY_WEIGHT 
      ELSE -1 
     END as weighted_score 
     FROM 
      score s 
     WHERE 
      s.critic_id = ANY(ARRAY['CRITIC_BOB_0213', 'CRITIC_AMY_9671']) 
     GROUP BY 
      s.film_id, s.critic_id 
    ) 
sub 
GROUP BY 
    f_id 
ORDER BY 
    avg desc 
LIMIT 
    10; 

希望这将帮助其他人的未来。

+0

'CRITIC_BOB_WEIGHT'是表中的一个字段还是一个变量? – Hambone

+0

这是用户输入的变量。在我的后端代码中,我只有一个循环,它构造了循环遍历用户输入的查询,并在需要时使用此变量添加“WHEN”行。 – appel

+0

我看到的唯一问题是,这看起来没有很大的可扩展性......我假设用户可以提供任意数量的批评和权重,并且您希望查询能够处理它? – Hambone