总和的10%()Postgres

时间:2013-10-07 07:36:37

标签: sql postgresql postgresql-9.1 postgresql-9.2 top-n

我希望在Postgres服务器上拉出总值的前10%。

所以我用sum(transaction.value)求和一个值,我想要值的前10%

1 个答案:

答案 0 :(得分:3)

从我在你的评论中收集到的内容,我认为你想:

  1. 按客户汇总交易以获得每位客户的总数。
  2. 列出实际拥有交易且花费最多的客户的前10%。
  3. WITH cte AS (
       SELECT t.customer_id, sum(t.value) AS sum_value
       FROM   transaction t
       GROUP  BY 1
       )
    SELECT *, rank() OVER (ORDER BY sum_value DESC) AS sails_rank
    FROM   cte
    ORDER  BY sum_value DESC
    LIMIT (SELECT count(*)/10 FROM cte)
    

    重点

    • 最好在这里使用CTE,使计数更便宜。

    • JOINcustomer之间的transaction会自动排除没有交易的客户。我在这里假设关系完整性(customer_id上的fk约束)。

    • 划分bigint / int会有效地截断结果(向下舍入到最接近的整数)。您可能对此相关问题感兴趣:
      PostgreSQL equivalent for TOP n WITH TIES: LIMIT "with ties"?

    • 我添加了一个您没有要求的sails_rank列,但似乎符合您的要求。

    • 如您所见,我甚至没有在查询中包含表customer。假设您在customer_id上有一个外键约束,那将是多余的(并且更慢)。如果您希望结果中有来自客户的其他列,请将customer加入上述查询的结果

    WITH cte AS (
       SELECT t.customer_id, sum(t.value) AS sum_value
       FROM   transaction t
       GROUP  BY 1
       )
    SELECT c.customer_id, c.name, sub.sum_value, sub.sails_rank
    FROM  (
       SELECT *, rank() OVER (ORDER BY sum_value DESC) AS sails_rank
       FROM   cte
       ORDER  BY sum_value DESC
       LIMIT (SELECT count(*)/10 FROM cte)
       ) sub
    JOIN  customer c USING (customer_id);