Sắp xếp bảng và nhận vị trí


7

Tôi có thể sắp xếp một bảng bằng mã sau đây:SELECT * FROM Persons ORDER BY LastName

Nhưng tôi muốn có được thứ hạng / vị trí của một người sử dụng thứ tự đó.

Ví dụ: khi tôi sắp xếp bảng Person theo độ tuổi, tôi muốn có được thứ hạng / vị trí của một người có tên Antinio Trias.

Làm thế nào tôi sẽ làm điều đó?

Câu trả lời:


6

Các chức năng phân tích chưa được triển khai trong MySQL. Có một số cách để khắc phục hạn chế này.

  • Tham gia bảng để tự sử dụng không bình đẳng nhưng >hay >=và sau đó sử dụng GROUP BYCOUNT(*)(những gì @deszo được về cơ bản làm - tự LEFT JOIN). Nhược điểm là nó có thể không đủ nhanh, đặc biệt nếu bạn đang tự tham gia một truy vấn / chế độ xem phức tạp.

  • Sử dụng các biến MySQL (Tôi nên thêm một Cảnh báo rất lớn : sử dụng biến MySQL theo cách này có thể bị phá vỡ trong các bản phát hành MySQL trong tương lai . Đây không phải là hành vi được bảo đảm):

    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 ;

Bạn có thể kiểm tra trong SQL-Fiddle: test-1


Trong các DBMS khác, có các hàm cửa sổ (phân tích), bạn có thể có cùng một truy vấn nhỏ gọn hơn nhiều:

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 ;

Kiểm tra trong SQL-Fiddle (SQL-Server, Postgres, Oracle): test-2


4

Có thể không phải là giải pháp hiệu quả tốt nhất:

SELECT p.*, (SELECT count(*) FROM Persons WHERE LastName > p.LastName) AS Rank
FROM Persons p ORDER BY LastName
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.