2012-10-08 14 views
44

Podemos encontrar el índice de la primera aparición de una subcadena dada en MySQL usando la función INSTR() de la siguiente manera.Último índice de una subcadena dada en MySQL

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

Sería mostrar 5, la primera aparición de la subcadena especificada que es en este caso un carácter de subrayado _.

Necesito obtener la última aparición de un determinado carácter (o una subcadena) algo así como el método Java lastIndexOf(String str) de la clase String pero no puedo encontrar ninguna función incorporada en MySQL.

¿Hay alguna función incorporada para lograr esto en MySQL?

+0

Si alguien tiene una solución, por favor agréguela como respuesta. – Tiny

Respuesta

97

@Marc B estaba cerca. En MySQL, sentencia siguiente devuelve 12:

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

Anticipándose a una posible utilización del valor, la siguiente declaración extrae la parte izquierda de la cadena antes del último guión bajo (es decir, _):

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

El resultado es "first_middle". Si desea incluir el delimitador, utilice:

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

Sería bueno si mejoran LOCALIZAR tener una opción para iniciar la búsqueda desde la derecha.

Si desea que la parte derecha de la cadena después de que el último espacio es una solución mejor:

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

Esto devuelve "último".

+0

@Tiny, estoy seguro de que probablemente encuentres una respuesta por ahora. Tuve el mismo problema y quería publicar una solución. – curt

+0

Claro que mi solución fue la primera en su respuesta. Gracias por la respuesta. – Tiny

+2

SUBSTRING_INDEX es muy útil. ¿tenemos algo similar en php? – mikewasmike

4

Creo que se puede utilizar SUBSTRING_INDEX de esta manera:

select substring_index(string, delimiter,-1) 

-1 comenzará al final de la cadena.

+0

Claro que sé que puedo, pero muestra ** substring ** en sí mismo (después de que se ha realizado la extracción) y no la posición del índice de esa subcadena. En este caso, mostraría 'día' pero necesito mostrar' 12' el índice de la subcadena especificada. – Tiny

+0

¿Cuánto dura el texto? ¿Puedes revertirlo y luego usar las funciones de localización o localización? Sé que no es la forma más ideal, pero funcionaría. – rizalp1

+0

En cualquier caso, no puedo pensar en invertir la cadena porque necesito extraer otro texto dentro de la cadena en función del último índice encontrado. – Tiny

3

Combo de reversa/indexof?

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

lo descomponen, dada su 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 
123456789
     ^
+0

'SUBSTRING_INDEX ('yad_doog_a_evah', '_')' emite un error 'Recuento de parámetros incorrecto en el llamar a la función nativa 'SUBSTRING_INDEX''. Requiere un tercer parámetro como 'SUBSTRING_INDEX ('yad_doog_a_evah', '_', 1)' que produce una subcadena 'yad' y no el primer índice de' _' que es '4' en este caso. Gracias por la respuesta. – Tiny

+0

¿Tiene una solución? Podría hacerlo, pero de una manera fea que es odiosa y evitable. Gracias. – Tiny

14

Si no desea que la sobrecarga de INVERSA utilice la siguiente:

LEFT 
(
    'Have_a_good_day', 
    LENGTH('Have_a_good_day') - LENGTH(SUBSTRING_INDEX('Have_a_good_day','_',-1))-1 
) 
+0

Esto es exactamente lo que tengo y creo que es mejor que usar 'reverse' – Fr0zenFyr

+4

Esto difiere de la respuesta aceptada en la forma en que una cadena sin el delimitador, como' Have', se convierte en una cadena vacía en vez de 'Have'. – l33t

0

Mientras que los códigos anteriores funcionan con éxito para un solo carácter, fracasaron cuando los utiliza para encontrar la última aparición de una subcadena . Por tanto, recomiendo el siguiente código para esta tarea:

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

Esto debería devolver 17

0

He encontrado esto como un buen truco para hacerlo:

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

Esto devolverá el índice del última ocurrencia (= 12).Básicamente, busca la parte correcta de la cadena después del último delimitador y luego busca la posición de esta subcadena en toda la cadena, lo que le otorga la posición :)

Si desea obtener la subcadena a la izquierda de esto puede usar:

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