web-dev-qa-db-fra.com

Fractionner la chaîne par la position du délimiteur à l'aide d'Oracle SQL

J'ai une chaîne et je voudrais diviser cette chaîne par délimiteur à une certaine position.

Par exemple, ma chaîne est F/P/O et le résultat que je recherche est:

Screenshot of desired result

Par conséquent, je voudrais séparer la chaîne par le séparateur le plus éloigné.
Remarque: certaines de mes chaînes sont F/O également pour lequel mon SQL ci-dessous fonctionne bien et renvoie le résultat souhaité.

Le SQL que j'ai écrit est le suivant:

SELECT Substr('F/P/O', 1, Instr('F/P/O', '/') - 1) part1, 
       Substr('F/P/O', Instr('F/P/O', '/') + 1)    part2 
FROM   dual

et le résultat est:

Screenshot of unexpected result

Pourquoi cela se produit-il et comment puis-je le réparer?

23
Avinesh Kumar

Vous voulez utiliser regexp_substr() pour cela. Cela devrait fonctionner pour votre exemple:

select regexp_substr(val, '[^/]+/[^/]+', 1, 1) as part1,
       regexp_substr(val, '[^/]+$', 1, 1) as part2
from (select 'F/P/O' as val from dual) t

Ici , à propos, est le violon SQL.

Oops. J'ai raté la partie de la question où il est écrit le délimiteur last. Pour cela, nous pouvons utiliser regex_replace() pour la première partie:

select regexp_replace(val, '/[^/]+$', '', 1, 1) as part1,
       regexp_substr(val, '[^/]+$', 1, 1) as part2
from (select 'F/P/O' as val from dual) t

Et ici est ce SQL Fiddle correspondant.

19
Gordon Linoff

Par conséquent, je voudrais séparer la chaîne par le séparateur le plus éloigné.

Je sais que c’est une vieille question, mais c’est une exigence simple pour laquelle SUBSTR et INSTR suffirait. REGEXP sont toujours plus lent et beaucoup de ressources en CP que les anciennes fonctions subtsr et instr.

SQL> WITH DATA AS
  2    ( SELECT 'F/P/O' str FROM dual
  3    )
  4  SELECT SUBSTR(str, 1, Instr(str, '/', -1, 1) -1) part1,
  5         SUBSTR(str, Instr(str, '/', -1, 1) +1) part2
  6  FROM DATA
  7  /

PART1 PART2
----- -----
F/P   O

Comme vous avez dit que vous voulez le délimiteur le plus éloigné, cela signifierait le premier délimiteur du inverse.

Votre approche était correcte, mais il vous manquait le start_position dans INSTR . Si start_position est négatif, la fonction INSTR compte le nombre total de caractères commençant_position à partir de la fin de la chaîne, puis effectue une recherche vers le début de la chaîne.

30
Lalit Kumar B