2016-04-09 4 views
2

Nach dem Suchen und Ausprobieren vieler Beispiele, konnte ich dies nicht herausfinden. Hoffe, du kannst mir helfen.UPDATE Rang in 3 Möglichkeiten innerhalb der Gruppe

Das ist mein Tisch Test:

+-------+-----------+----------+---------+---------+-------+ 
    |Id  | Class | Score | Rank1 | Rank2 | Rank3 | 
    +-------+-----------+----------+---------+---------+-------+ 
    |1  |  1  |  9 | 0 | 0 | 0 | 
    |2  |  1  |  9 | 0 | 0 | 0 | 
    |3  |  1  |  8 | 0 | 0 | 0 | 
    |4  |  1  |  7 | 0 | 0 | 0 | 
    |5  |  2  |  9 | 0 | 0 | 0 | 
    |6  |  2  |  8 | 0 | 0 | 0 | 
    |7  |  2  |  8 | 0 | 0 | 0 | 
    |8  |  2  |  7 | 0 | 0 | 0 | 
    |9  |  2  |  6 | 0 | 0 | 0 | 
    +-------+-----------+----------+---------+---------+-------+ 

Was würde Ich mag meine Tabelle Test mit 3 Arten von Rankings UPDATE:

  1. = Rang 1 = mit konsekutiver auf Score pro Klasse Rang Ränge (kein Doppel)
  2. = Rang 2 = Ranked auf Score pro Klasse mit aufeinanderfolgenden Rängen (mit Doppel)
  3. = Rang 3 = Ranked auf Score pro Klasse ohne aufeinanderfolgende Ränge (mit dou ble)

Z. B:

+-------+-----------+----------+---------+---------+-------+ 
    |Id  | Class | Score | Rank1 | Rank2 | Rank3 | 
    +-------+-----------+----------+---------+---------+-------+ 
    |1  |  1  |  9 | 1 | 1 | 1 | 
    |2  |  1  |  9 | 2 | 1 | 1 | 
    |3  |  1  |  8 | 3 | 2 | 3 | 
    |4  |  1  |  7 | 4 | 3 | 4 | 
    |5  |  2  |  9 | 1 | 1 | 1 | 
    |6  |  2  |  8 | 2 | 2 | 2 | 
    |7  |  2  |  8 | 3 | 2 | 2 | 
    |8  |  2  |  7 | 4 | 3 | 4 | 
    |9  |  2  |  6 | 5 | 4 | 5 | 
    +-------+-----------+----------+---------+---------+-------+ 

HINWEIS: Es hat in einer UPDATE-Anweisung anwendbar.

Für 1. ich gefunden habe (aber nicht herausfinden kann, wie es ein Update zu machen):

SET @prev := null; 
SET @cnt := 0; 
SELECT IF(@prev <> Class, @cnt := 1, @cnt := @cnt + 1) AS Rank, @prev := Class 
FROM Test 
ORDER BY Class; 

Für 3. ich gefunden habe (aber nicht herausfinden kann, wie man es machen ein UPDATE):

SELECT a.Id, 
    a.Score, 
    a.Class, 
    count(b.Score)+1 as Rank 
FROM Test a left join Test b 
    on a.Score>b.Score and a.Class=b.Class 
GROUP BY a.Id, 
     a.Score, 
     a.Class; 

ich habe die Ergebnisse hinzugefügt, wenn Punkte auf Werte mit Dezimalstellen berechnet. Seltsame Rankings erscheinen:

SET @prev_class = 0,@class = 0,@prev_score = 0,@score = 0,@rank3 = 0,@count=0; 
UPDATE 1i SET 
    Score_pq_raw_rank = (@prev_class := IFNULL(@class,0)), 
    Score_pq_raw_rank = (@class := Profile_id), 
    Score_pq_raw_rank = (@prev_score := IFNULL(@score,-1)), 
    Score_pq_raw_rank = (@score := Score_pq_raw), 
    Score_pq_raw_rank = (
    CASE WHEN @prev_class != @class THEN @rank3 := 1 
     WHEN @prev_class = @class AND @prev_score = @score THEN @rank3 
     WHEN @prev_class = @class AND @prev_score != @score THEN @rank3:[email protected][email protected] 
    END), 
    Score_pq_raw_rank = (CASE WHEN @prev_class != @class THEN @count := 0 
     WHEN @prev_class = @class AND @prev_score = @score THEN @count := @count + 1 
     WHEN @prev_class = @class AND @prev_score != @score THEN @count := 0 
    END), 
    Score_pq_raw_rank = @rank3 
ORDER BY Profile_id ASC, Score_pq_raw DESC, Rowresult_id ASC; 

+--------------+--------------+------------+-------------------+ 
| Rowresult_id | Score_pq_raw | Profile_id | Score_pq_raw_rank | 
+--------------+--------------+------------+-------------------+ 
|   1 | 3.69054000 |   1 |     1 | 
|   2 | 0.10568000 |   1 |     2 | 
|   3 | -2.08058000 |   1 |     3 | 
|   4 | -2.07316000 |   1 |     3 | 
|   5 | -2.39066000 |   1 |     3 | 
|   6 | -10.23852000 |   2 |     3 | 
|   7 | -8.77718000 |   2 |     2 | 
|   8 | -7.38480000 |   2 |     1 | 
|   9 | -13.49128000 |   2 |     4 | 
|   10 | -19.36774000 |   2 |     5 | 
+--------------+--------------+------------+-------------------+ 
+1

Welche SQL-Anweisungen haben Sie versucht? – BLE

+0

Normalerweise würden Sie abgeleitete Daten nicht speichern – Strawberry

+0

Ich habe meine Frage aktualisiert – Dev

Antwort

0

Hier ist die Auswahl, die Ihnen Ihre gewünschten Ränge gibt.

SELECT Id,Class,Score, 
     @prev_class := IFNULL(@class,0), 
     @class := Class, 
     @prev_score := IFNULL(@score,-1), 
     @score := Score, 

     CASE WHEN @prev_class != @class THEN @rank1 := 1 
      ELSE @rank1 := @rank1 + 1 
     END as rank1, 
     CASE WHEN @prev_class != @class THEN @rank2 := 1 
      WHEN @prev_class = @class AND @prev_score = @score THEN @rank2 
      WHEN @prev_class = @class AND @prev_score != @score THEN @rank2:[email protected]+1 
     END as rank2, 
     CASE WHEN @prev_class != @class THEN @rank3 := 1 
      WHEN @prev_class = @class AND @prev_score = @score THEN @rank3 
      WHEN @prev_class = @class AND @prev_score != @score THEN @rank3:[email protected][email protected] 
     END as rank3, 
     CASE WHEN @prev_class != @class THEN @count := 0 
      WHEN @prev_class = @class AND @prev_score = @score THEN @count := @count + 1 
      WHEN @prev_class = @class AND @prev_score != @score THEN @count := 0 
     END as count 
FROM Test 
ORDER BY Class ASC, Score DESC, Id ASC; 

und hier ist das Update, das diese Arbeit tun würde, verwende ich nur mehrfach SET Rank1 weil MySQL nicht einfach Satz @variables zu ermöglichen scheint, ohne das Ergebnis für einige Spalten mit ...

SET @prev_class = 0,@rank1 = 0,@score = 0,@prev_score = 0,@class =0,@rank2=0,@rank3 =0,@count=0; 
UPDATE Test SET 
     rank1 = (@prev_class := IFNULL(@class,0)), 
     rank1 = (@class := Class), 
     rank1 = (@prev_score := IFNULL(@score,-1)), 
     rank1 = (@score := Score), 
     rank1 = (
     CASE WHEN @prev_class != @class THEN @rank1 := 1 
      ELSE @rank1 := @rank1 + 1 
     END), 
     rank2 = (
     CASE WHEN @prev_class != @class THEN @rank2 := 1 
      WHEN @prev_class = @class AND @prev_score = @score THEN @rank2 
      WHEN @prev_class = @class AND @prev_score != @score THEN @rank2:[email protected]+1 
     END), 
     rank3 = (
     CASE WHEN @prev_class != @class THEN @rank3 := 1 
      WHEN @prev_class = @class AND @prev_score = @score THEN @rank3 
      WHEN @prev_class = @class AND @prev_score != @score THEN @rank3:[email protected][email protected] 
     END), 
     rank3 = (CASE WHEN @prev_class != @class THEN @count := 0 
      WHEN @prev_class = @class AND @prev_score = @score THEN @count := @count + 1 
      WHEN @prev_class = @class AND @prev_score != @score THEN @count := 0 
     END), 
     rank3 = @rank3 
ORDER BY Class ASC, Score DESC, Id ASC 

sqlfiddle

aktualisieren Rank1 nur

SET @prev_class = 0,@class = 0,@prev_score = 0,@score = 0,@rank1 = 0; 
UPDATE Test SET 
     rank1 = (@prev_class := IFNULL(@class,0)), 
     rank1 = (@class := Class), 
     rank1 = (@prev_score := IFNULL(@score,-1)), 
     rank1 = (@score := Score), 
     rank1 = (
     CASE WHEN @prev_class != @class THEN @rank1 := 1 
      ELSE @rank1 := @rank1 + 1 
     END) 
ORDER BY Class ASC, Score DESC, Id ASC; 

aktualisieren rank2 nur

SET @prev_class = 0,@class = 0,@prev_score = 0,@score = 0,@rank2 = 0; 
UPDATE Test SET 
     rank2 = (@prev_class := IFNULL(@class,0)), 
     rank2 = (@class := Class), 
     rank2 = (@prev_score := IFNULL(@score,-1)), 
     rank2 = (@score := Score), 
     rank2 = (
     CASE WHEN @prev_class != @class THEN @rank2 := 1 
      WHEN @prev_class = @class AND @prev_score = @score THEN @rank2 
      WHEN @prev_class = @class AND @prev_score != @score THEN @rank2:[email protected]+1 
     END) 
ORDER BY Class ASC, Score DESC, Id ASC; 

aktualisieren rank3 nur

SET @prev_class = 0,@class = 0,@prev_score = 0,@score = 0,@rank3 = 0,@count=0; 
UPDATE Test SET 
     rank3 = (@prev_class := IFNULL(@class,0)), 
     rank3 = (@class := Class), 
     rank3 = (@prev_score := IFNULL(@score,-1)), 
     rank3 = (@score := Score), 
     rank3 = (
     CASE WHEN @prev_class != @class THEN @rank3 := 1 
      WHEN @prev_class = @class AND @prev_score = @score THEN @rank3 
      WHEN @prev_class = @class AND @prev_score != @score THEN @rank3:[email protected][email protected] 
     END), 
     rank3 = (CASE WHEN @prev_class != @class THEN @count := 0 
      WHEN @prev_class = @class AND @prev_score = @score THEN @count := @count + 1 
      WHEN @prev_class = @class AND @prev_score != @score THEN @count := 0 
     END), 
     rank3 = @rank3 
ORDER BY Class ASC, Score DESC, Id ASC; 
+0

Dies ist Fenominal !! Nun, da einige meiner DBs Rang 1 benötigen, andere Rang 2 etc. Ich kann nicht herausfinden, wie ich jeden Rang einzeln aktualisieren kann. Ich habe einige Teile geschnitten, aber nur eine 0 aktualisiert. Könntest du mir helfen, sie in 3 separate UPDATE-Rankings zu schneiden oder mir vielleicht auf die richtige Weise zeigen, wie? – Dev

+0

Sie möchten jeden Rang separat wie 3 verschiedene Updates aktualisieren? –

+0

Wenn das möglich ist, wäre dies sehr hilfreich – Dev