2016-06-30 268 views
0

我有壽表:訂單產品。 如何在MySQL 5.6中生成排名?SQL。銷售排名加入

在產品價值相同的情況下,排名也必須相同。 下面我需要通過計數排名

SELECT 
    count(productpk), productpk, 
    @prev := @curr, 
    @curr := count(productpk), 
    @rank := IF(@prev = @curr, @rank, @rank+1) AS rank 
FROM orders AS om 
JOIN products AS p ON om.PK=p.p_order, 
    (SELECT @curr := null, @prev := null, @rank := 0) sel1 
GROUP BY productpk ORDER BY count(productpk); 

enter image description here

有效的結果是(計數 - >等級):

  • 2 - > 3
  • 2 - > 3
  • 4 - > 2
  • 4 - > 2
  • 6 - > 1

回答

1

這個查詢應該做的。

SELECT 
sq.productpk, 
sq.cp, 
@rank := IF(@prev = sq.cp, @rank, @rank + 1) AS rank, 
@prev := sq.cp 
FROM 
(
    SELECT 
    productpk, 
    COUNT(productpk) AS cp 
    FROM orders o 
    JOIN products p ON o.PK = p.p_order 
    GROUP BY productpk 
) sq 
, (SELECT @prev := NULL, @rank := 0) var_init_subquery 
ORDER BY sq.cp DESC 

SELECT子句中的順序很重要。當你做這樣的事第一

@prev := @curr, 

,然後像這樣

@rank := IF(@prev = @curr,... 

這是毫無意義的,因爲@prev將永遠等於@curr。順便提一下,@curr也是無意義的。

您必須將@prev與您的IF()函數中的當前行進行比較。之後,您將當前行分配給@prev。當讀取下一行時,@prev仍然保持前一行的值。

最後你必須把你的分組查詢放在子查詢中。人們不會想到,這是必要的,因爲查詢就像

  1. 邏輯處理了來自
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. ORDER BY
  6. 選擇

但是MySQL不這樣做,至少在涉及用戶定義變量時不這樣做。看到這個簡單的測試來證明:

[email protected]:playground > select a, @r:[email protected]+1 as r from bar, (select @r := 0) sq; 
+------+------+ 
| a | r | 
+------+------+ 
| 1 | 1 | 
| 1 | 2 | 
| 1 | 3 | 
| 1 | 4 | 
| 1 | 5 | 
| 1 | 6 | 
| 1 | 7 | 
| 1 | 8 | 
| 1 | 9 | 
| 1 | 10 | 
| 2 | 11 | 
| 2 | 12 | 
| 2 | 13 | 
| 2 | 14 | 
| 2 | 15 | 
+------+------+ 
15 rows in set (0.00 sec) 

[email protected]:playground > select a, @r:[email protected]+1 as r from bar, (select @r := 0) sq group by a; 
+------+------+ 
| a | r | 
+------+------+ 
| 1 | 1 | 
| 2 | 11 | 
+------+------+ 
2 rows in set (0.00 sec) 
0

則可以使用帶相同的結果集

mysql> select DONATUR,COUNT(DISTINCT AREA) ,@curRank := @curRank + 1 AS rank from funding,(SELECT @curRank := 0) r group by Donatur;    +---------+----------------------+------+ 
| DONATUR | COUNT(DISTINCT AREA) | rank | 
+---------+----------------------+------+ 
| Mr.X |     3 | 1 | 
| Mr.Y |     1 | 2 | 
| Mr.Z |     2 | 3 | 
| sss  |     0 | 4 | 
| wwww |     0 | 5 | 
+---------+----------------------+------+ 
5 rows in set (0.00 sec) 

SELECT x.DONATUR,x.area,if(x.rank>y.rank,y.rank,x.rank) AS rank FROM (select DONATUR,COUNT(DISTINCT AREA) as area ,@curRank := @curRank + 1 AS rank from funding,(SELECT @curRank := 0) r group by Donatur) x LEFT JOIN (select DONATUR,COUNT(DISTINCT AREA) as area ,@curRank2 := @curRank2 + 1 AS rank from funding,(SELECT @curRank2 := 0) r group by Donatur) y on y.rank<>x.rank and x.area=y.area; 
+---------+------+------+ 
| DONATUR | area | rank | 
+---------+------+------+ 
| Mr.X | 3 | 1 | 
| Mr.Y | 1 | 2 | 
| Mr.Z | 2 | 3 | 
| sss  | 0 | 4 | 
| wwww | 0 | 4 | 
+---------+------+------+ 
5 rows in set (0.00 sec) 
內加入做