Tabelle sortieren und Position ermitteln

7

Ich kann eine Tabelle mit dem folgenden Code sortieren:SELECT * FROM Persons ORDER BY LastName

Aber ich wollte das Ranking / die Position einer Person erhalten, die diese Reihenfolge verwendet.

Wenn ich beispielsweise die Personentabelle nach Alter sortiere, möchte ich den Rang / die Position einer Person namens Antinio Trias ermitteln.

Wie mache ich das?

Jayson Tamayo
quelle

Antworten:

6

Analytische Funktionen wurden in MySQL noch nicht implementiert. Es gibt einige Möglichkeiten, diese Einschränkung zu überwinden.

  • Verbinden der Tabelle mit sich selbst mit nicht Gleichheit, sondern >oder >=und dann mit GROUP BYund COUNT(*)(was @deszo im Wesentlichen tut - ein Selbst LEFT JOIN). Nachteil ist, dass es möglicherweise nicht schnell genug ist, insbesondere wenn Sie sich einer komplexen Abfrage / Ansicht selbst anschließen.

  • Verwenden von MySQL-Variablen (Ich sollte jedoch eine große Warnung hinzufügen : Die Verwendung von MySQL-Variablen auf diese Weise kann in zukünftigen MySQL-Versionen fehlerhaft sein . Dies ist kein garantiertes Verhalten):

    SELECT LastName
         , FirstName
         , RowNumber
         , Rank
         , DenseRank
         , RowNumber_OverPartitionBy
    FROM
      ( SELECT p.*,
               @rown := @rown + 1 AS RowNumber
             , @rnk :=  CASE WHEN LastName = @prev_lastname
                          THEN @rnk
                          ELSE @rown 
                        END AS Rank
             , @drnk := CASE WHEN LastName = @prev_lastname
                          THEN @drnk
                          ELSE @drnk + 1 
                        END AS DenseRank
             , @rowp := CASE WHEN LastName = @prev_lastname
                          THEN @rowp + 1
                          ELSE 1 
                        END AS RowNumber_OverPartitionBy
             , @prev_lastname := LastName
        FROM 
            Person p 
          CROSS JOIN
            ( SELECT @rown := 0, @rnk := 0
                   , @drnk := 0, @rowp := 0
            ) AS dummy 
        ORDER BY LastName
               , FirstName            
      ) AS p 
    ORDER BY LastName
           , FirstName ;

Sie können in SQL-Fiddle testen : test-1


In anderen DBMS mit Fensterfunktionen (Analysefunktionen) können Sie dasselbe in einer viel kompakteren Abfrage verwenden:

SELECT LastName
     , FirstName
     , Row_Number() OVER(ORDER BY LastName, FirstName)
         AS RowNumber
     , Rank() OVER(ORDER BY LastName)
         AS Rank
     , Dense_Rank() OVER(ORDER BY LastName)
         AS DenseRank
     , Row_Number() OVER( PARTITION BY LastName
                          ORDER BY FirstName)
         AS RowNumber_OverPartitionBy
FROM
    Person p 
ORDER BY 
    LastName
  , FirstName ;

Test in SQL-Fiddle (SQL-Server, Postgres, Oracle): Test-2

ypercubeᵀᴹ
quelle
4

Möglicherweise nicht die leistungsstärkste Lösung:

SELECT p.*, (SELECT count(*) FROM Persons WHERE LastName > p.LastName) AS Rank
FROM Persons p ORDER BY LastName
dezso
quelle