2010-08-31 43 views
2

我有一个客户表如下:需要一个PostgreSQL的查询分组和顺序

customername, ordername, amount 
============================= 
bob, book,  20 
bob, computer, 40 
steve,hat,  15 
bill, book, 12 
bill, computer, 3 
steve, pencil, 10 
bill, pen,  2 

我想运行一个查询,得到以下结果:

customername, ordername, amount 
============================= 
bob, computer, 40 
bob, book,  20 
bob, ~total~, 60 
steve, hat,  15 
steve, pencil, 10 
steve, ~total~,25 
bill, book, 12 
bill, computer, 3 
bill, pen,  2 
bill, ~total~, 17 

我想要的金额每个客户从最大值到最小值以及一个新的订单名称都被定义为“总共〜”(必须始终是每个客户的最后一行),并将结果作为同一客户的所有金额的总和。 因此,在上面的例子中,bob应该是总数= 60以来的第一个,第二个(总数= 25)和第三个(总数= 17)。

回答

8

用途:

SELECT x.customername, 
     x.ordername, 
     x.amount 
    FROM (SELECT a.customername, 
       a.ordername, 
       a.amount, 
       y.rk, 
       1 AS sort 
      FROM CUSTOMERS a 
      JOIN (SELECT c.customername, 
         ROW_NUMBER() OVER (ORDER BY SUM(c.amount) DESC) AS rk 
        FROM CUSTOMERS c 
       GROUP BY c.customername) y ON y.customername = a.customername 
     UNION ALL 
     SELECT b.customername, 
       '~total~', 
       SUM(b.amount), 
       ROW_NUMBER() OVER (ORDER BY SUM(b.amount) DESC) AS rk,    
       2 AS sort 
      FROM CUSTOMERS b 
     GROUP BY b.customername) x 
ORDER BY x.rk, x.customername, x.sort, x.amount DESC 

你可以看看使用GROUP BY ROLLUP,但ordername值将是NULL所以你必须进行后处理它来获取替换为“〜总〜” ......

+0

我喜欢“幻影列进行排序”的想法。我正在构建一个花哨的ORDER BY,它涉及到与'〜total〜''的比较,但是你的方式更加干净 - 即使有人下了一个名为''total〜''的命令,它也能工作。 – 2010-08-31 04:25:26

+0

感谢您的解决方案。但是,它仍然没有按降序排列金额列。 – Rowshan 2010-08-31 05:09:07

+0

将x.amount DESC添加到最后一行(ORDER BY x.customername,x.sort,x.amount DESC)中。 再次感谢 – Rowshan 2010-08-31 05:12:43