Oracle requête pour trouver toutes les occurrences d'un charcter dans une chaîne de caractères
Je dois écrire un Oracle de la requête en crapaud pour trouver toutes les occurrences d'un caractère dans une chaîne. Par exemple, si je suis à la recherche de R
dans la chaîne SSSRNNSRSSR
, il doit retourner les positions 4, 8 et 11.
Je suis nouveau à l'Oracle et j'ai essayé cette.
select instr(mtr_ctrl_flags, 'R', pos + 1, 1) as pos1
from mer_trans_reject
where pos in ( select instr(mtr_ctrl_flags, 'R', 1, 1) as pos
from mer_trans_reject
);
où mtr_ctrl_flags
est le nom de la colonne. J'obtiens un message d'erreur indiquant que pos
est un identifiant invalide.
- Défi intéressant. Ce serait un très étrange requête, ou vous aurez à écrire une procédure stockée. Ou il y a toujours ce dernier, malheureux possibilité qu'il existe une fonction très pratique je ne sais pas de...
- (Auto-écrite) fonction pourrait être plus efficace que l'utilisation de tout type de requête récursive.
- Il pourrait être, mais ne sous-estimez pas la surcharge d'appels de fonctions. Il serait intéressant de tester, si, mais actuellement, je n'ai que sqlfiddle, et je doute si c'est fiable plate-forme d'analyse comparative.
Vous devez vous connecter pour publier un commentaire.
L'extension de GolezTrol de réponse, vous pouvez utiliser des expressions régulières pour réduire de façon significative le nombre de requêtes récursives vous n':
REGEXP_COUNT() renvoie le nombre de fois que le motif correspond, dans ce cas, le nombre de fois
R
existe dansSSSRNNSRSSR
. Cela limite le niveau de récursion le nombre exact que vous en avez besoin.INSTR() simplement des recherches pour l'indice de R dans votre chaîne.
level
est la profondeur de la récursivité, mais dans ce cas c'est aussi le niveau th occurrence de la chaîne que nous avons limité le nombre d'analyse requis.Si la chaîne que vous êtes désireux de choisir est plus compliqué que vous pourriez aller pour les expressions régulières sna REGEXP_INSTR() plutôt INSTR (), mais il sera plus lent (pas de beaucoup) et il n'est pas nécessaire sauf si requis.
Simple indice de référence demandés:
Les deux se connectent PAR des solutions serait d'indiquer que l'utilisation de REGEXP_COUNT est 20% plus rapide sur une chaîne de cette taille.
Le pipeline fonction de table est juste un peu plus lent, mais il serait intéressant de voir comment il se comporte sur de grandes chaînes de caractères avec beaucoup de matchs.
LISTAGG()
serait l'approche traditionnelle @RajeenaSafeer, voir sqlfiddle.com/#!4/d41d8/15010C'est une solution:
dual
est un construit dans le tableau qui ne renvoie qu'une seule ligne. Très pratique!connect by
vous permet de construire des requêtes récursives. Il est souvent utilisé pour générer des listes à partir de l'arbre de données (les relations parent/enfant). Il permet de plus ou moins répéter la requête en face d'elle. Et vous avez des domaines particuliers, commelevel
qui vous permet de vérifier à quel point la récursivité est allé.Dans ce cas, je l'utilise pour diviser la chaîne de caractères et de retourner une ligne pour chaque personnage. À l'aide de
level
, je peux répéter la requête et obtenir un personnage jusqu'à la fin de la chaîne est atteint.Alors c'est juste une question de retourner le
pos
pour toutes les lignes contenant le caractère'R'
À prendre a_horse_with_no_name du défi voici une autre réponse avec un pipeline fonction de table.
Un pipeline fonction renvoie un tableau, que vous pouvez interroger normalement. Je m'attends à ce que plus de chaînes avec un grand nombre de matchs, ce sera mieux que la requête récursive mais comme avec tout ce test vous-même d'abord.
Puis dans l'ordre pour y accéder:
SQL Violon