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 BY
và COUNT(*)
(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