2010-04-30 11 views
8

Quiero extraer una palabra de una columna de cadena de una tabla.¿Cuál es el equivalente de REGEXP_SUBSTR en mysql?

description 
=========================== 
abc order_id: 2 xxxx yyy aa 
mmm order_id: 3 nn kk yw 

Resultado esperado conjunto

order_id 
=========================== 
2 
3 

Tabla será en la mayoría tienen 100 filas, longitud del texto es de ~ 256 Char y la columna siempre tiene uno order_id presente. Entonces el rendimiento no es un problema.

En Oracle, puedo usar REGEXP_SUBSTR para este problema. ¿Cómo resolvería esto en MySQL?

Editar 1

estoy usando localizar y SUBSTR para resolver el problema. El código es feo Diez minutos después de escribir el código, estoy maldiciendo al tipo que escribió un código tan feo.

No encontré la función REGEXP_SUBSTR en documentos de MySQL. Pero espero que exista ...

Respuesta a: ¿Por qué no se puede optimizar la mesa? ¿Por qué se almacenan los datos de una manera tan tonta?

El ejemplo que di solo denota el problema que intento resolver. En un escenario real, estoy usando un software de colas de terceros basado en DB para ejecutar tareas asincrónicas. La cola serializa el objeto Ruby como texto. No tengo control sobre la estructura de la tabla O el formato de datos. Las tareas en la cola pueden ser recurrentes. En nuestra configuración de prueba, algunas de las tareas recurrentes están fallando debido a datos obsoletos. Tengo que eliminar estas tareas para evitar el error. Dichos errores no son comunes, por lo tanto, no quiero mantener una tabla de sombras normalizada.

Respuesta

3

Al igual que Konerak dijo, no hay un equivalente de REGEXP_SUBSTR en MySql. Se podría hacer lo que tiene el uso de la lógica SUBSECUENCIA, pero es feo:

SELECT 
    SUBSTRING(lastPart.end, 1, LOCATE(' ', lastPart.end) - 1) AS orderId 
FROM 
    (
    SELECT 
     SUBSTRING(dataset.description, LOCATE('order_id: ', dataset.description) + LENGTH('order_id: ')) AS end 
    FROM 
     (
     SELECT 'abc order_id: 2 xxxx yyy aa' AS description 
     UNION SELECT 'mmm order_id: 3 nn kk yw' AS description 
     UNION SELECT 'mmm order_id: 1523 nn kk yw' AS description 
    ) AS dataset 
    ) AS lastPart 

Editar: se podía probar este user defined function proporcionar acceso a perl expresiones regulares en MySQL

SELECT 
    PREG_CAPTURE('/.*order_id:\s(\d+).*/', dataset.description,1) 
FROM 
    (
    SELECT 'abc order_id: 2 xxxx yyy aa' AS description 
    UNION SELECT 'mmm order_id: 3 nn kk yw' AS description 
    UNION SELECT 'mmm order_id: 1523 nn kk yw' AS description 
) AS dataset 
+1

Esto es lo que estoy haciendo. +1 por tomarse el tiempo para escribir esto ... –

+1

Respuesta editada para usar CHAR_LENGTH() en lugar de LENGTH(), este último devuelve el tamaño ocupado en Bytes, y no la longitud de la cadena. Tendrás problemas con UTF8 por ejemplo –

1

No hay equivalente MySQL. El REGEXP de MySQL se puede usar para hacer coincidir cadenas, pero no para transformarlas.

Puede intentar trabajar con procedimientos almacenados y una gran cantidad de lógica REEMPLAZAR/SUBSTRINGAR, o hacerlo en su lenguaje de programación, que debería ser la opción más fácil.

¿Pero está seguro de que su formato de datos está bien elegido? Si necesita el order_id, ¿no tendría sentido almacenarlo en una columna diferente, para que pueda poner índices, usar combinaciones y "me gusta"?

+1

No siempre podemos elegir nuestro formato de datos. Por ejemplo, cuando realizamos migraciones de datos o importamos cosas desde otro sistema, con frecuencia tenemos que manejar todo lo que recibimos. – APC

+0

Lea mi pregunta actualizada por qué tengo esa información. –

0

o puede hacer esto y ahorrarse la fealdad:

select SUBSTRING_INDEX(SUBSTRING_INDEX('habc order_id: 2 xxxx yyy aa',' ',3),' ',-1); 
Cuestiones relacionadas