【问题标题】:Summing and ordering at once一次求和和排序
【发布时间】:2013-03-10 07:43:30
【问题描述】:

我有一张订单表。在那里,我需要找出哪 3 个 partner_id 的 amount_totals 总和最大,并将这 3 个从大到小排序。

    testdb=# SELECT amount_total, partner_id FROM sale_order;
     amount_total | partner_id 
    --------------+------------
          1244.00 |          9
          3065.90 |         12
          3600.00 |          3
          2263.00 |         25
          3000.00 |         10
          3263.00 |          3
           123.00 |         25
          5400.00 |         12
    (8 rows)

刚启动SQL,我觉得很混乱……

【问题讨论】:

  • amount_total 是一个非常不幸的名称,它显然根本不是总数。应该是 amount 或更具描述性的东西。合计金额可以是amount_totalamount_year 或其他。您要列出合计金额还是单独的行?
  • 另外:如果4个合伙人的总金额相同怎么办?全选4个?选3?定义方式。

标签: sql postgresql aggregate-functions greatest-n-per-group


【解决方案1】:

合计金额

如果您想列出汇总金额,可以很简单:

SELECT partner_id, sum(amount_total) AS amout_suptertotal
FROM   sale_order
GROUP  BY 1
ORDER  BY 2 DESC
LIMIT  3;

GROUP BY 1 中的 1 是一个数值参数,表示SELECT 列表中的位置。在这种情况下,只是GROUP BY partner_id 的符号快捷方式。

这忽略了超过三个合作伙伴符合条件并任意选择 3 个的特殊情况(因为缺乏定义)。

个人金额

SELECT partner_id, amount_total
FROM   sale_order
JOIN  (
   SELECT partner_id, rank() OVER (ORDER BY sum(amount) DESC) As rnk
   FROM   sale_order
   GROUP  BY 1
   ORDER  BY 2
   LIMIT  3
   ) top3 USING (partner_id)
ORDER  BY top3.rnk;

另一方面,如果有 3 个以上的合作伙伴有资格进入前 3 名,则这个包括所有同行。window function rank() 为您提供。

这里的技术是在子查询top3 中按partner_id 分组,并在聚合之后附加窗口函数rank()(窗口函数在聚合函数之后执行)。 ORDER BY 在窗口函数之后应用,LIMIT 最后应用。多合一子查询。

然后我将基表加入到这个子查询中,这样结果中就只剩下前几名了,并按rnk排序。

窗口函数需要 PostgreSQL 8.4 或更高版本。

这是相当高级的东西。你应该从更简单的东西开始学习 SQL。

【讨论】:

    【解决方案2】:
    select amount_total, partner_id
    from (
        select
            sum(amount_total) amount_total,
            partner_id
        from sale_order
        group by partner_id
    ) s
    order by amount_total desc
    limit 3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-23
      相关资源
      最近更新 更多