PostgreSQL排名和相关

时间:2014-01-23 10:58:54

标签: sql performance postgresql ranking

我有一个表,用于存储用户ID及其在不同类别中的点数。用户数量将不断变化。这些点也会不断变化(就像stackoverflow中的点一样)。因此,登录的用户将看到一个仪表板,其中显示了3个类别中的每个类别 - 你有850分,有950名用户在你前面。这是我现在的查询 -

WITH USERS AS (
   SELECT COUNT(*) TOT 
   FROM user_pointS
) 
SELECT ' You have ' || points_cat1 ||' points and there are '|| tot-rnk || ' ahead of you '   
FROM (
    SELECT ID,  
           points_cat1, 
           rank() OVER (ORDER BY  points_cat1 DESC ) AS RNK 
    FROM user_pointS
  ) AS RANKED, 
    USERS
WHERE ID = 10

有更好的方法(性能方面)吗?我将不得不重复3列?

1 个答案:

答案 0 :(得分:0)

嗯,你可以在没有CTE的情况下做到这一点:

SELECT ' You have ' || points_cat1 ||' points and there are '|| tot-rnk || ' ahead of you '   
FROM (SELECT ID, points_cat1, 
              rank() OVER (ORDER BY points_cat1 DESC ) AS RNK ,
              count(*) over () as TOT
      FROM user_pointS
     ) RANKED
WHERE ID = 10;

您可以同时为所有三个类别执行此操作:

SELECT ' You have ' || points_cat1 ||' points and there are '|| tot-rnk1 || ' ahead of you ',
       ' You have ' || points_cat2 ||' points and there are '|| tot-rnk2 || ' ahead of you ',
       ' You have ' || points_cat3 ||' points and there are '|| tot-rnk3 || ' ahead of you '

FROM (SELECT ID, points_cat1, points_cat2, points_cat3,
              rank() OVER (ORDER BY points_cat1 DESC ) AS RNK ,
              rank() OVER (ORDER BY points_cat2 DESC ) AS RNK1 ,
              rank() OVER (ORDER BY points_cat3 DESC ) AS RNK2 ,
              count(*) over () as TOT
      FROM user_pointS
     ) RANKED
WHERE ID = 10;

您可以使用反向排名替换tot-rnk

 rank() OVER (ORDER BY points_cat1 ASC ) AS RNK

但你想测试一下,以确保它能为你提供你期望的结果。