web-dev-qa-db-fra.com

Dernier index d'une sous-chaîne donnée dans MySQL

Nous pouvons trouver l'index de la première occurrence d'une sous-chaîne donnée dans MySQL en utilisant la fonction INSTR() comme suit.

SELECT instr('Have_a_good_day', '_') AS index_position

Il afficherait 5, la première occurrence de la sous-chaîne spécifiée qui est dans ce cas un trait de soulignement _.

Je dois obtenir la dernière occurrence d'un caractère donné (ou d'une sous-chaîne) comme la méthode Java lastIndexOf(String str) de la classe String mais je ne trouve aucune fonction intégrée dans MySQL.

Existe-t-il une fonctionnalité intégrée pour y parvenir dans MySQL?

51
Tiny

@Marc B était proche. Dans MySQL, l'instruction suivante renvoie 12:

SELECT CHAR_LENGTH("Have_a_good_day") - LOCATE('_', REVERSE("Have_a_good_day"))+1;

En anticipant une utilisation possible de la valeur, l'instruction suivante extrait la partie gauche de la chaîne avant le dernier trait de soulignement (c'est-à-dire, _):

SELECT LEFT("first_middle_last", CHAR_LENGTH("first_middle_last") - LOCATE('_', REVERSE("first_middle_last")));

Le résultat est "first_middle". Si vous souhaitez inclure le délimiteur, utilisez:

SELECT LEFT("first_middle_last", CHAR_LENGTH("first_middle_last") - LOCATE('_', REVERSE("first_middle_last"))+1);

Ce serait bien s'ils amélioraient LOCATE d'avoir une option pour lancer la recherche de la droite.

Si vous voulez la bonne partie de la chaîne après le dernier espace, une meilleure solution est: 

SELECT SUBSTRING_INDEX("first_middle_last", '_', -1);

Ceci retourne "dernier".

112
curt

Si vous ne voulez pas les frais généraux de REVERSE, utilisez ce qui suit:

LEFT
(
   'Have_a_good_day', 
   LENGTH('Have_a_good_day') - LENGTH(SUBSTRING_INDEX('Have_a_good_day','_',-1))-1
)
18
N D

Je pense que vous pouvez utiliser substring_index de cette façon:

select substring_index(string, delimiter,-1)

-1 commencera à la fin de la chaîne.

7
rizalp1

Combo de reverse/indexof?

SELECT LENGTH(string) - SUBSTRING_INDEX(REVERSE(string), delimiter) + 1

le décomposer, étant donné votre Have_a_good_day:

REVERSE('Have_a_good_day') -> yad_doog_a_evaH
SUBSTRING_INDEX('yad_doog_a_evah', '_') -> 4
LENGTH('Have_a_good_day') -> 15
15 - 4 + 1 -> 12

Have_a_good_day
123456789012345
           ^
3
Marc B

J'ai trouvé cela comme une bonne astuce pour le faire:

SELECT LOCATE(SUBSTRING_INDEX('Have_a_good_day', '_', -1),'Have_a_good_day')-1 AS indexpos;

Cela renverra l'index de la dernière occurrence (= 12). Fondamentalement, vous recherchez la partie droite de la chaîne après le dernier séparateur, puis la position de cette sous-chaîne dans la chaîne entière, ce qui vous donne la position :)

Si vous souhaitez obtenir la sous-chaîne à gauche de ceci, vous pouvez utiliser:

SELECT
  SUBSTRING('Have_a_good_day', 1, 
     LOCATE(SUBSTRING_INDEX('Have_a_good_day', '_', -1),'Have_a_good_day')-1) 
  AS sub;
1
Asped

Bien que les codes ci-dessus fonctionnent avec un seul caractère, ils ont échoué lorsque je les ai utilisés pour rechercher la dernière occurrence d'une sous-chaîne. Je recommande donc le code ci-dessous pour cette tâche:

SELECT LENGTH("my father is my father")
        - LOCATE('father', REVERSE("my father is my father"))-(LENGTH('father')-1)

Cela devrait retourner 17

0
Adewole Kayode