web-dev-qa-db-fra.com

Comment sélectionner une sous-chaîne dans Oracle SQL jusqu'à un caractère spécifique?

Disons que j'ai une colonne de table qui a des résultats comme:

ABC_blahblahblah
DEFGH_moreblahblahblah
IJKLMNOP_moremoremoremore

J'aimerais pouvoir écrire une requête qui sélectionne cette colonne dans la table, mais renvoie uniquement la sous-chaîne jusqu'au caractère Underscore (_). Par exemple:

ABC
DEFGH
IJKLMNOP

La fonction SUBSTRING ne semble pas être à la hauteur de la tâche car elle est basée sur la position et la position du soulignement varie.

J'ai pensé à la fonction TRIM (la fonction RTRIM en particulier):

SELECT RTRIM('listofchars' FROM somecolumn) 
FROM sometable

Mais je ne suis pas sûr de savoir comment cela fonctionnerait, car cela semble uniquement supprimer une certaine liste/un ensemble de caractères et je ne suis vraiment qu'après les personnages menant au personnage Underscore.

64
Pretzel

En combinant SUBSTR, INSTR et NVL (pour les chaînes sans trait de soulignement), vous obtiendrez ce que vous voulez:

SELECT NVL(SUBSTR('ABC_blah', 0, INSTR('ABC_blah', '_')-1), 'ABC_blah') AS output
  FROM DUAL

Résultat:

output
------
ABC

Utilisation:

SELECT NVL(SUBSTR(t.column, 0, INSTR(t.column, '_')-1), t.column) AS output
  FROM YOUR_TABLE t

Référence:

Addenda

Si vous utilisez Oracle 10g +, vous pouvez utiliser regex via REGEXP_SUBSTR .

122
OMG Ponies

Cela peut être fait en utilisant REGEXP_SUBSTR facilement.

Veuillez utiliser 

REGEXP_SUBSTR('STRING_EXAMPLE','[^_]+',1,1) 

STRING_EXAMPLE est votre chaîne.

Essayer:

SELECT 
REGEXP_SUBSTR('STRING_EXAMPLE','[^_]+',1,1) 
from dual

Cela résoudra votre problème.

34
user1717270

Vous devez obtenir la position du premier trait de soulignement (avec INSTR), puis obtenir la partie de la chaîne du 1er caractère à (pos-1) en utilisant substr.

  1  select 'ABC_blahblahblah' test_string,
  2         instr('ABC_blahblahblah','_',1,1) position_underscore,
  3         substr('ABC_blahblahblah',1,instr('ABC_blahblahblah','_',1,1)-1) result
  4*   from dual
SQL> /

TEST_STRING      POSITION_UNDERSCORE RES
---------------- ------------------  ---
ABC_blahblahblah                  4  ABC

Documentation Instr

Documentation Susbtr

7
Rajesh Chamarthi
SELECT REGEXP_SUBSTR('STRING_EXAMPLE','[^_]+',1,1)  from dual

est la bonne réponse, telle que publiée par user1717270

Si vous utilisez INSTR, il vous donnera la position d'une chaîne supposée contenir "_". Et si ça ne marche pas? La réponse sera donc 0. Par conséquent, lorsque vous souhaitez imprimer la chaîne, une NULL..__ est imprimée. Exemple: Si vous souhaitez supprimer le domaine d'un "Host.domain". Dans certains cas, vous n’avez que le nom abrégé, c’est-à-dire "Hôte". Très probablement, vous souhaitez imprimer "Host". Eh bien, avec INSTR cela vous donnera une NULL car il n’a trouvé aucun ".", C’est-à-dire qu’il imprimera de 0 à 0. Avec REGEXP_SUBSTR vous obtiendrez la bonne réponse dans tous les cas:

SELECT REGEXP_SUBSTR('Host.DOMAIN','[^.]+',1,1)  from dual;

Hôte

et

SELECT REGEXP_SUBSTR('Host','[^.]+',1,1)  from dual;

Hôte

5
Loquillo Amigo

Une autre possibilité serait d'utiliser REGEXP_SUBSTR.

2
EvilTeach

Rappelez-vous ceci si toutes vos chaînes de la colonne n'ont pas de trait de soulignement .__ (... ou sinon si la valeur null sera la sortie):

SELECT COALESCE
(SUBSTR("STRING_COLUMN" , 0, INSTR("STRING_COLUMN", '_')-1), 
"STRING_COLUMN") 
AS OUTPUT FROM DUAL
0
SJOH

Pour trouver une sous-chaîne à partir d'une chaîne longue:

string_value:=('This is String,Please search string 'Ple');

Ensuite, pour trouver la chaîne 'Ple' à partir de String_value, nous pouvons faire comme:

select substr(string_value,instr(string_value,'Ple'),length('Ple')) from dual;

Vous trouverez le résultat: Ple

0
vishal Pathak