Вы можете создать (временную) MyISAM таблицу со столбцом AUTO_INCREMENT rank
в составном ПЕРВИЧНОМ КЛЮЧЕ.Таким образом, rank
будет иметь одну последовательность на ID
, когда вы заполняете таблицу различными (id, item_code)
комбинациями.Затем вы можете объединить эту таблицу с исходными данными.
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>
Демонстрация
Если вы хотите использовать ее в одном запросе, вы можете попробовать это:
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
Демонстрация
Имейте в виду, что порядок вычисления операций в операторе SQL не определен.Поэтому, когда вы читаете и пишете пользовательскую переменную в одном и том же операторе, вы передаете подробности реализации.
В MySQL 8 или MariaDB 10.2 это будет:
SELECT id, item_code,
DENSE_RANK() OVER (PARTITION BY id ORDER BY item_code) as `rank`
FROM test t
-- WHERE <several filters>
Демо