I need the following, Can anyone please help me do it.
Rank Cust_Type Cust_Name Revenue
1 Top A 10000
2 Top B
I found a problem with the solution using CASE, @curRow, and @curType. It depends on the execution plan MySQL uses to process the query. For example, it shows up if you add a join to the query. Then there is no guarantee that the rank is going to be computed correctly.
Making a slight change to the answer:
CREATE TABLE sales (cust_type_id int, cust_name varchar(10), revenue int);
CREATE TABLE cust_type (cust_type_id int, type_name varchar(10));
INSERT INTO cust_type VALUES (1, 'Bottom');
INSERT INTO cust_type VALUES (2, 'Top');
INSERT INTO sales VALUES (2, 'A', 10000);
INSERT INTO sales VALUES (2, 'B', 9000);
INSERT INTO sales VALUES (2, 'C', 8000);
INSERT INTO sales VALUES (1, 'X', 5000);
INSERT INTO sales VALUES (1, 'Y', 6000);
INSERT INTO sales VALUES (1, 'Z', 7000);
If I query only the sales table I get the rank in the correct order, but if I join to the cust_type table the rank values are no longer correct
SELECT (
CASE s.cust_type_id
WHEN @curType
THEN @curRow := @curRow + 1
ELSE @curRow := 1 AND @curType := s.cust_type_id END
) AS rank,
t.type_name,
s.cust_name,
s.revenue
FROM sales s,
cust_type t,
(SELECT @curRow := 0, @curType := 0) r
WHERE s.cust_type_id = t.cust_type_id
ORDER BY t.type_name DESC, s.revenue DESC;
Result:
+------+-----------+-----------+---------+
| rank | type_name | cust_name | revenue |
+------+-----------+-----------+---------+
| 1 | Top | A | 10000 |
| 2 | Top | B | 9000 |
| 3 | Top | C | 8000 |
| 3 | Bottom | Z | 7000 |
| 2 | Bottom | Y | 6000 |
| 1 | Bottom | X | 5000 |
+------+-----------+-----------+---------+
MySQL is running the initial query into a temp table and then the ORDER BY is executing against the temp table after a rank was already computed.