Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Ranks in one table

Tags:

sql

mysql

I need the following, Can anyone please help me do it.

Rank   Cust_Type   Cust_Name   Revenue
1      Top         A           10000
2      Top         B           9000
3      Top         C           8000
1      Bottom      X           5000
2      Bottom      Y           6000
3      Bottom      Z           7000

I need separate ranks for Top and Bottom Cust_Type and all this is in MySQL.

like image 431
Nikhil Avatar asked Jul 01 '10 23:07

Nikhil


People also ask

How do you rank multiple ranks?

To rank multiple references, you only need a formula. Select a blank cell which you will place the ranking result, enter this formula =1+SUMPRODUCT(($A$2:$A$12=A2)*($B$2:$B$12>B2)), press Enter key, and drag fill handle over the cells to apply this formula.

How do you rank in multiple columns?

Select a blank cell which you will place the ranking result, for instance, D2, and type this formula =RANK(B2,$B$2:$B$7)+SUMPRODUCT(--($B$2:$B$7=$B2),--(C2<$C$2:$C$7)), press Enter key, and then drag fill handle over the cells which use this formula.


1 Answers

This is a bit tricky. You may want to use variables, such as in the following example:

SELECT    ( 
            CASE cust_type 
            WHEN @curType 
            THEN @curRow := @curRow + 1 
            ELSE @curRow := 1 AND @curType := cust_type END
          ) + 1 AS rank,
          cust_type,
          cust_name,
          revenue
FROM      sales,
          (SELECT @curRow := 0, @curType := '') r
ORDER BY  cust_type DESC, revenue DESC;

The (SELECT @curRow := 0, @curType := '') r part allows the variable initialization without requiring a separate SET command.

Test case:

CREATE TABLE sales (cust_type varchar(10), cust_name varchar(10), revenue int);

INSERT INTO sales VALUES ('Top', 'A', 10000);
INSERT INTO sales VALUES ('Top', 'B', 9000);
INSERT INTO sales VALUES ('Top', 'C', 8000);
INSERT INTO sales VALUES ('Bottom', 'X', 5000);
INSERT INTO sales VALUES ('Bottom', 'Y', 6000);
INSERT INTO sales VALUES ('Bottom', 'Z', 7000);

Result:

+------+-----------+-----------+---------+
| rank | cust_type | cust_name | revenue |
+------+-----------+-----------+---------+
|    1 | Top       | A         |   10000 |
|    2 | Top       | B         |    9000 |
|    3 | Top       | C         |    8000 |
|    1 | Bottom    | Z         |    7000 |
|    2 | Bottom    | Y         |    6000 |
|    3 | Bottom    | X         |    5000 |
+------+-----------+-----------+---------+
6 rows in set (0.00 sec)

Another test case:

CREATE TABLE sales (cust_type varchar(10), cust_name varchar(10), revenue int);

INSERT INTO sales VALUES ('Type X', 'A', 7000);
INSERT INTO sales VALUES ('Type X', 'B', 8000);
INSERT INTO sales VALUES ('Type Y', 'C', 5000);
INSERT INTO sales VALUES ('Type Y', 'D', 6000);
INSERT INTO sales VALUES ('Type Y', 'E', 4000);
INSERT INTO sales VALUES ('Type Z', 'F', 4000);
INSERT INTO sales VALUES ('Type Z', 'G', 3000);

Result:

+------+-----------+-----------+---------+
| rank | cust_type | cust_name | revenue |
+------+-----------+-----------+---------+
|    1 | Type Z    | F         |    4000 |
|    2 | Type Z    | G         |    3000 |
|    1 | Type Y    | D         |    6000 |
|    2 | Type Y    | C         |    5000 |
|    3 | Type Y    | E         |    4000 |
|    1 | Type X    | B         |    8000 |
|    2 | Type X    | A         |    7000 |
+------+-----------+-----------+---------+
7 rows in set (0.00 sec)

You can obviously order the cust_type in ascending order instead of descending. I used descending just to have Top before Bottom in the original test case.

like image 60
Daniel Vassallo Avatar answered Oct 05 '22 21:10

Daniel Vassallo