Vous pouvez créer un MyISAM (temporaire) table avec un rank
AUTO_INCREMENT colonne dans une CLÉ PRIMAIRE composite. De cette façon, rank
aura une séquence par ID
lorsque vous remplissez le tableau avec un (id, item_code)
distinct combinaisons. Vous pouvez ensuite joindre cette table avec les données d'origine.
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>
Si vous le souhaitez en une seule requête, vous pouvez essayer celle-ci :
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
Sachez que l'ordre d'évaluation des opérations dans une instruction SQL n'est pas défini. Ainsi, lorsque vous lisez et écrivez une variable utilisateur dans la même instruction, vous relayez les détails d'implémentation.
Dans MySQL 8 ou MariaDB 10.2 ce serait :
SELECT id, item_code,
DENSE_RANK() OVER (PARTITION BY id ORDER BY item_code) as `rank`
FROM test t
-- WHERE <several filters>