tags:

views:

43

answers:

1

I have a customers table as following:

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

I want to run a query to get the following result:

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

I want the amount for each customer to be ordered from max to min and a new ordername as "~total~" (must always be the last row for each customer) with a result as sum of all amount for the same customer. So, in above example, bob should be the first since the total=60, steve the second (total=25) and bill the third (total=17).

+5  A: 

Use:

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

You could look at using GROUP BY ROLLUP, but the ordername value would be NULL so you'd have to post-process it to get that replaced with "~total~"...

OMG Ponies
I like the "phantom column for sorting" idea. I was in the process of building a fancy ORDER BY that involved a comparison with `'~total~'`, but your way's much cleaner -- it works even if someone places an order named `'~total~'`.
j_random_hacker
Thanks for the solution. However, it's still not ordering the amount column in descending order.
Rowshan
Adding x.amount DESC to the last line (ORDER BY x.customername, x.sort, x.amount DESC) orders in decending.Thanks again
Rowshan
Now the last thing to be resolved is to show the max first. So, first bob, second steve and last bill.
Rowshan
@Rowshan: Resolved.
OMG Ponies