2017-10-10 96 views
0

我試圖根據第一列和第二列進行查詢設置排列列。排名一樣分區上不存在的MySQL第一列和第二列的MySQL SET排名

例如,

+----+-------+--------+------+ 
| id | First | Second | Rank | 
+----+-------+--------+------+ 
| 1 | a  |  10 |  | 
| 2 | a  |  9 |  | 
| 3 | b  |  10 |  | 
| 4 | b  |  7 |  | 
| 5 | a  |  1 |  | 
| 6 | b  |  1 |  | 
+----+-------+--------+------+ 

+----+-------+--------+------+ 
| id | First | Second | Rank | 
+----+-------+--------+------+ 
| 1 | a  |  10 | 3 | 
| 2 | a  |  9 | 2 | 
| 3 | b  |  10 | 3 | 
| 4 | b  |  7 | 2 | 
| 5 | a  |  1 | 1 | 
| 6 | b  |  1 | 1 | 
+----+-------+--------+------+ 

的排名不會繼續。當它到達'First'列'a'的最後一個值時,它會從1開始。

它必須是SET而不是SELECT。 我不介意使用SELECT,但我的觀點是我不想從數據庫檢索數據,但設置值。

提前歡呼隊友。

+0

但是,爲什麼要存儲派生數據? – Strawberry

+0

不能每次請求訂購 –

+0

我不明白。什麼是成本? – Strawberry

回答

0
DROP TABLE IF EXISTS my_table; 

CREATE TABLE my_table 
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY 
,first CHAR(1) NOT NULL 
,second INT NOT NULL 
); 

INSERT INTO my_table VALUES 
(1,'a',10), 
(2,'a',9), 
(3,'b',10), 
(4,'b',7), 
(5,'a',1), 
(6,'b',1); 

SELECT id 
    , first 
    , second 
    , rank 
    FROM 
    (SELECT x.* 
      , CASE WHEN @prev = first THEN @i:[email protected]+1 ELSE @i:=1 END rank 
      , @prev:=first 
     FROM my_table x 
      , (SELECT @prev:=null,@i:=0) vars 
     ORDER 
      BY first 
      , second 
      , id 
    ) a 
ORDER 
    BY id; 
+----+-------+--------+------+ 
| id | first | second | rank | 
+----+-------+--------+------+ 
| 1 | a  |  10 | 3 | 
| 2 | a  |  9 | 2 | 
| 3 | b  |  10 | 3 | 
| 4 | b  |  7 | 2 | 
| 5 | a  |  1 | 1 | 
| 6 | b  |  1 | 1 | 
+----+-------+--------+------+ 
6 rows in set (0.00 sec) 
+0

任何其他解決方案,而不是刪除表? –

+0

哦,我放棄了。表情符號撞在牆上撞在哪裏? – Strawberry

+0

謝謝你的嘗試。我只是想讓我的老闆滿意,所以我可以在更好的職位上談判薪水。 –

0

一種方法是相關的子查詢。對於rank()你可以這樣做:

select t.*, 
     (select count(*) + 1 
     from t t2 
     where t2.first = t.first and t2.second < t.second 
     ) as rank 
from t; 

隊伍有貓膩與變量(dense_rank()row_number()更簡單)來處理。

編輯:

這很容易變成一個update

update t join 
     (select t.*, 
       (select count(*) + 1 
       from t t2 
       where t2.first = t.first and t2.second < t.second 
       ) as new_rank 
     from t 
     ) tt 
     on t.id = tt.id 
    set t.rank = tt.new_rank; 
+0

感謝您的想法,但正如我所說,它必須更新而不是選擇 –

0

想出了與我一直在尋找一個解決方案。 我不確定這些查詢是否完全安全,但至今沒有危害。

SET @rank = 0, @First = '' 
UPDATE 'Table' SET 
rank = IF(@First = First, @rank:= @rank +1, @rank := 1 AND @First := First) 
ORDER BY First ASC, Second; 
相關問題