Bạn có thể tạo một MyISAM (tạm thời) bảng có AUTO_INCREMENT rank
trong một KHÓA CHÍNH tổng hợp. Bằng cách này, rank
sẽ có một chuỗi cho mỗi ID
khi bạn điền vào bảng với (id, item_code)
riêng biệt các tổ hợp. Sau đó, bạn có thể nối bảng đó với dữ liệu gốc.
CREATE TEMPORARY TABLE tmp_rank(
id INT,
item_code varchar(50),
rank INT AUTO_INCREMENT,
PRIMARY KEY (id, rank)
) engine=MyISAM
SELECT DISTINCT NULL as rank, id, item_code
FROM test t
-- WHERE <several filters>
ORDER BY id, item_code
;
SELECT t.*, x.rank
FROM tmp_rank x
JOIN test t USING(id, item_code)
-- WHERE <several filters>
Nếu bạn muốn nó trong một truy vấn, bạn có thể thử truy vấn sau:
SELECT id, item_code,
CASE
WHEN id = @curId AND item_code = @curCode
THEN @curRank
WHEN id <> @curId THEN @curRank := 1
ELSE @curRank := @curRank + 1
END AS rank,
@curId := id,
@curCode := item_code
FROM test t
CROSS JOIN (SELECT
@curRank := 0,
cast(@curCode := null as signed),
cast(@curId := NULL as char)
) r
#WHERE <several filters>
ORDER BY id, item_code
Lưu ý rằng thứ tự đánh giá của các hoạt động trong một câu lệnh SQL không được xác định. Vì vậy, khi bạn đọc và ghi một biến người dùng trong cùng một câu lệnh, bạn sẽ chuyển tiếp về chi tiết triển khai.
Trong MySQL 8 hoặc MariaDB 10.2 nó sẽ là:
SELECT id, item_code,
DENSE_RANK() OVER (PARTITION BY id ORDER BY item_code) as `rank`
FROM test t
-- WHERE <several filters>