J'ai un problème de tri avec Oracle 10G. Je ne sais pas si cela est spécifique à 10g ou non.
J'ai le tableau suivant: p> Effectuer le nom générique Sélectionnez le nom de table_name Order by 1 Code> Produit: P>
A.1
A.2
A.3
A.4
A.5
A.5.1
A.5.2
A.5.3
A.5.10
A.5.10.1
5 Réponses :
Ce qui suit peut vous donner une idée de quoi faire. Pour commander des valeurs du formulaire "A.", vous pouvez commander par la longueur de l'expression suivie de l'expression. Ainsi, A.1 et A.2 sont avant A.10, car leur longueur est plus courte.
Vous pouvez étendre ceci, avec une commande de la manière suivante: p>
Je ne suis pas sûr de suivre la logique du code. Y a-t-il une parenthèse manquante ou constitue le substrateur ultérieur, LEN, SUBSTR dans la première déclaration LEN?
C'est une assez bonne solution, mais elle gère seulement une quantité limitée de points.
@ Luke101. . . Le but de la "..." est d'indiquer que le code peut être étendu à l'aide de la même structure que les autres lignes.
Voici un moyen de le faire. Je ne dis pas que c'est le seul ou même le meilleur moyen, mais c'est A STRAND> WAY: SELECT ID,
NAME
FROM
(SELECT ID, NAME,
INSTR(NAME, '.', 1, 1) AS FIRST_DOT_INDEX,
INSTR(NAME, '.', 1, 2) AS SECOND_DOT_INDEX,
INSTR(NAME, '.', 1, 3) AS THIRD_DOT_INDEX,
INSTR(NAME, '.', 1, 4) AS FOURTH_DOT_INDEX
FROM test_table)
ORDER BY SUBSTR(NAME, 1, FIRST_DOT_INDEX-1),
TO_NUMBER(SUBSTR(NAME, FIRST_DOT_INDEX+1, (CASE WHEN SECOND_DOT_INDEX>0
THEN SECOND_DOT_INDEX-1
ELSE LENGTH(NAME)
END - FIRST_DOT_INDEX))),
TO_NUMBER(CASE WHEN SECOND_DOT_INDEX = 0 AND THIRD_DOT_INDEX = 0
THEN '0'
ELSE SUBSTR(NAME, SECOND_DOT_INDEX+1, (CASE WHEN THIRD_DOT_INDEX>0
THEN THIRD_DOT_INDEX-1
ELSE LENGTH(NAME)
END - SECOND_DOT_INDEX))
END),
TO_NUMBER(CASE WHEN THIRD_DOT_INDEX > 0
THEN SUBSTR(NAME, THIRD_DOT_INDEX+1, LENGTH(NAME) - THIRD_DOT_INDEX)
ELSE '0'
END);
Ceci compte-t-il que j'ai des longueurs de caractères et de sections de points?
Essayez ceci ici est un violon p> p>
Cela fonctionne définitivement. Pouvez-vous expliquer ce qui se passe? En outre, c'est une requête lourde qui prend beaucoup de temps pour générer. Est-ce que c'est à cause de l'avec / remplacer ou la concaténation dans l'ordre par? Je vous remercie.
Tout d'abord, il en fait un XML (pas vraiment nécessaire, peut être fait avec des substrateurs et destrs aussi - en réalité, cela peut coûter la performance). Ensuite, il faut chaque noeud (une partie entre points) et les pads avec des zéros à être de haute longueur (disons 5). Maintenant, il peut être trié
Utilisation de Regex peut résoudre votre problème,
select * from new_table order by to_number(regexp_replace(name,'[[:alpha:].]*'));
Cette solution ne triera pas A.5.11 avant A.5.10.1
Ce type de fonctionne, mais les trie en fonction de la longueur de la chaîne d'abord, puis dans le bon ordre.
Ma question a été répondue dans un autre poste que j'ai posté pour un problème similaire mais non liée. Grâce à ACHEONG87 pour la solution.
Oracle SQL Regexp_replace Correspondant à P> P>