Ce qui suit peut fonctionner pour les alphanumériques. Cependant, soyez averti que le comportement n'est pas défini pour les valeurs non alphanumériques.
WITH A (A, N) AS (
SELECT A, 3 + LEN(A) FROM (
SELECT 'a1'
UNION ALL
SELECT 'a10'
UNION ALL
SELECT 'a11'
UNION ALL
SELECT 'ab2'
UNION ALL
SELECT 'ab21'
UNION ALL
SELECT 'ab22'
UNION ALL
SELECT 'a1a'
UNION ALL
SELECT 'a1b'
UNION ALL
SELECT 'a1'
UNION ALL
SELECT 'a1a'
UNION ALL
SELECT 'a1b'
UNION ALL
SELECT 'a2'
UNION ALL
SELECT 'a3'
UNION ALL
SELECT 'a9'
UNION ALL
SELECT 'ab1'
UNION ALL
SELECT 'ab2'
UNION ALL
SELECT 'ab3'
) T (A)
), B (A, N, I, C, D, X) AS (
SELECT A, N, 3, CAST(SUBSTRING(A, 1, 1) AS VARCHAR(255)), CAST(SUBSTRING(A, 2, 1) AS VARCHAR(255)), CAST('' AS VARCHAR(255)) FROM A
UNION ALL
SELECT A, N, I + 1, D, CAST(SUBSTRING(A, I, 1) AS VARCHAR(255)), CASE WHEN ASCII(C) BETWEEN 48 AND 57 AND ASCII(D) BETWEEN 48 AND 57 THEN CAST(X + CHAR(10 + ASCII(D)) AS VARCHAR(255)) WHEN 58 > ASCII(C) THEN CAST(X + C AS VARCHAR(255)) ELSE CAST(X + CHAR(3 + ASCII(C)) AS VARCHAR(255)) END FROM B WHERE I <= N
)
SELECT A FROM B WHERE I = N
ORDER BY X COLLATE Latin1_General_BIN
Le code trie actuellement en cas de manière sensible, mais il peut être modifié pour faire une affaire sorte insensible aussi bien, par exemple en utilisant
ORDER BY UPPER(X) COLLATE Latin1_General_BIN
ou
ORDER BY LOWER(X) COLLATE Latin1_General_BIN
est le format de chaîne cohérent? aussi quel est le dbms utilisé? –
Pas exactement, la partie numérique est précédée de 1-3 lettres. – AlexVPerl
Veuillez marquer votre question avec la base de données que vous utilisez. –