2009-08-05 8 views
0

I ont une table avec une colonne « otname » table1.otname contient plusieurs lignes de chaîne de caractères alpha-numérique ressemblant à l'échantillon de données suivant:lecture d'une partie d'une chaîne alphanumérique dans SQL

11.10.32. .UA.F.3.2.21.2.249.1

2001.1.1003. .A.LE.P.P

2010.1.1003. .A.LE.B.B

Je veux lire le quatrième numéro dans chaque chaîne (partie de la chaîne en gras) et d'écrire une requête dans Oracle 10g pour lire sa description stockée dans une autre table. Mon dilemme est d'écrire la première partie de la query.i.e. choisir le quatrième numéro de chaque chaîne dans une table

Ma deuxième question sera quelque chose comme ceci:

select description_text from table2 where sncode = 8281 -- fourth part of the data sample in every string 

Un grand merci.

novice

Répondre

0

Fonctionne avec 9i +:

WITH portion AS (
    SELECT SUBSTR(t.otname, INSTR(t.otname, ".", 1, 3)+1, INSTR(t.otname, ".", 1, 4)) 'sncode' 
    FROM TABLE t) 
SELECT t.description_text 
    FROM TABLE2 t 
    JOIN portion p ON p.sncode = t.sncode 

L'utilisation de SUBSTR devrait être évident; INSTR est utilisé pour trouver l'emplacement de la période (.), En commençant par le premier caractère de la chaîne (valeur de paramètre 1), lors de la troisième et quatrième apparition dans la chaîne. Vous pourriez avoir à soustraire un de la position retournée pour la 4ème instance de la période - tester cette première pour être sûr que vous obtenez les bonnes valeurs:

SELECT SUBSTR(t.otname, INSTR(t.otname, ".", 1, 3)+1, INSTR(t.otname, ".", 1, 4)) 'sncode' 
FROM TABLE t 

je affacturage sous-requête afin que le sous-chaîne se produit avant de vous joindre à la deuxième table. Cela peut être fait comme une sous-requête, mais l'affacturage de sous-requête est plus rapide.

+0

Je reçois l'erreur suivante quand je lance ci-dessus requête: ORA: 00923: mot clé FROM introuvable là où il était attendu :( – novice

+0

Je n'ai pas d'instance Oracle à tester, mais le seul point de contention que je peux voir est le "+1" dans le premier INSTR. Vous êtes sûr que vous avez un espace entre le FROM et le nom de la table dans ce que vous avez tenté d'exécuter? –

0

Les versions les plus récentes d'Oracle (y compris 10g) ont diverses fonctions d'expression régulière. Ainsi, vous pouvez faire quelque chose comme ceci:

where sncode = to_number(regexp_replace(otname, '^(\d+\.\d+\.\d+\.(\d+))?.+$', '\2')) 

Cela correspond à 3 séries de chiffres-suivi par un point et un quatrième ensemble groupé de chiffres, suivi par le reste de la chaîne, et renvoie une chaîne composé de tout cela entièrement remplacé par le premier groupe (le quatrième ensemble de chiffres).

Voici une requête complète (si je comprends bien votre description des deux tables correctement):

select t2.description_text 
from table1 t1, table2 t2 
where t2.sncode = to_number(regexp_replace(t1.otname, '^(\d+\.\d+\.\d+\.(\d+))?.+$', '\2')) 

Une autre regex alternative un peu plus courte:

where t2.sncode = to_number(regexp_replace(t1.otname, '^((\d+\.){3}(\d+))?.+$', '\3')) 
+0

J'ai couru votre requête et j'obtiens l'erreur suivante: ORA-01722: nombre non valide Des suggestions? – novice

+0

Je suppose que j'ai supposé que votre "sncode" était aussi une chaîne. Faites-moi savoir si c'est en fait un numéro. En attendant, je mets à jour ma réponse pour refléter cela, donc vous pouvez l'essayer (la fonction "to_number"). – epost

+0

merci. le code d'erreur est en fait un nombre. otname est alphanumérique – novice

Questions connexes