Hacer una busqueda de palabra completa en mysql

Iniciado por OssoH, 3 Noviembre 2021, 16:59 PM

0 Miembros y 1 Visitante están viendo este tema.

OssoH

Quiero encontrar los registros que tengan en el campo nombre la palabra DEC.   (acabado en punto).
Si uso el RLIKE tal y como os pongo a continuación no me funciona por culpa del punto


SELECT name
FROM ps_product p LEFT JOIN ps_product_lang pl ON (pl.id_product=p.id_product)
WHERE `name` RLIKE "[[:<:]]REVIVAL[[:>:]]"
AND `name` RLIKE "[[:<:]]DEC[[:>:]]"


me devuelve :
revival dec. gris marea
revival dec. arena acuada

En cambio si pongo en RLIKE el punto al final en DEC. no me funciona


SELECT name
FROM ps_product p LEFT JOIN ps_product_lang pl ON (pl.id_product=p.id_product)
WHERE `name` RLIKE "[[:<:]]REVIVAL[[:>:]]"
AND `name` RLIKE "[[:<:]]DEC.[[:>:]]"


No devuelve ningún registro.

¿porque cuando le pongo el 'punto' no funciona? Es que tengo palabras a buscar donde el punto está dentro del string a buscar y me da problemas.

¿alguna solución?
Gracias



#!drvy

Citar
¿porque cuando le pongo el 'punto' no funciona? Es que tengo palabras a buscar donde el punto está dentro del string a buscar y me da problemas.

¿alguna solución?

El punto en REGEX es un carácter especial. Debe ser escapado.  Considera esto:

Una base de datos llamada datos, con una sola columna varchar llamada dato. 3 inserts:

|Patata
|Patata-Frita
|Patata.Frita




Código (sql) [Seleccionar]
SELECT dato FROM datos WHERE dato RLIKE '.'

Esta consulta me devuelve todos los datos porque el punto equivale a cualquier caracter.

Código (sql) [Seleccionar]
SELECT dato FROM datos WHERE dato RLIKE 'Patata.'

Esta consulta me devuelve Patata-Frita y Patata.Frita porque el punto equivale a cualquier caracter.

Código (sql) [Seleccionar]
SELECT dato FROM datos WHERE dato RLIKE 'Patata\\.'

Esta consulta me devuelve solo Patata.Frita, porque he escapado el punto.


https://dev.mysql.com/doc/refman/8.0/en/regexp.html#regexp-syntax

Saludos

MinusFour

Cita de: #!drvy en  3 Noviembre 2021, 17:21 PM
El punto en REGEX es un carácter especial. Debe ser escapado.  Considera esto:

Una base de datos llamada datos, con una sola columna varchar llamada dato. 3 inserts:

|Patata
|Patata-Frita
|Patata.Frita




Código (sql) [Seleccionar]
SELECT dato FROM datos WHERE dato RLIKE '.'

Esta consulta me devuelve todos los datos porque el punto equivale a cualquier caracter.

Código (sql) [Seleccionar]
SELECT dato FROM datos WHERE dato RLIKE 'Patata.'

Esta consulta me devuelve Patata-Frita y Patata.Frita porque el punto equivale a cualquier caracter.

Código (sql) [Seleccionar]
SELECT dato FROM datos WHERE dato RLIKE 'Patata\\.'

Esta consulta me devuelve solo Patata.Frita, porque he escapado el punto.


https://dev.mysql.com/doc/refman/8.0/en/regexp.html#regexp-syntax

Saludos

Aunque escapes el punto, no vas a obtener un match en este caso. Si bien el punto es un carácter que significa cualquier carácter excepto saltos de línea, sin escaparse el punto puede representar el punto literalmente (y los otros caracteres como has puesto). Así que aquí debería poder hacer match a DEC.... (y también DECA, DECB etc).

Yo creo que el problema aquí es con el marcador de final de palabra:

[[:>:]]

En este caso, el delimitador de una palabra está dado por el mismo punto. Lo que significa que el punto nunca llega a ser parte de la palabra. Por lo tanto:

Código (sql) [Seleccionar]
'[[:<:]]PALABRA[[:>:]]'

PALABRA nunca hará match si incluye un punto (porque el punto es el delimitador que indica el final de la palabra).

OssoH

Gracias por la explicación.
Pero yo quiero que busque cadenas de palabras completas y no fragmentos de cadena donde tenga la cadena de busqueda.

Es decir, si tengo

|Patata
|Patata-Frita
|Patata.Frita


Y escribo
SELECT dato FROM datos WHERE dato RLIKE 'patata'

me devolveria los 3 registros porque contienen la palabra patata cuando solo me deberia devolver la primera [patata].
Es decir que busque palabras completas y se considera palabra completa la separada por un espacio.

Ej :
arbol caido  => 2 palabras
arbol.caido => 1 palabra

Espero haberme explicado bien
Gracias



[

MinusFour

Cita de: OssoH en  3 Noviembre 2021, 17:46 PM
Gracias por la explicación.
Pero yo quiero que busque cadenas de palabras completas y no fragmentos de cadena donde tenga la cadena de busqueda.

Es decir, si tengo

|Patata
|Patata-Frita
|Patata.Frita


Y escribo
SELECT dato FROM datos WHERE dato RLIKE 'patata'

me devolveria los 3 registros porque contienen la palabra patata cuando solo me deberia devolver la primera [patata].
Es decir que busque palabras completas y se considera palabra completa la separada por un espacio.

Ej :
arbol caido  => 2 palabras
arbol.caido => 1 palabra

Espero haberme explicado bien
Gracias



[

Entonces no puedes usar: [[:<:]] ni [[:>:]], porque esos caracteres consideran PATATA-FRITA como dos palabras. Podrías usar:

Código (sql) [Seleccionar]
"(^|[[:blank:]]+)DEC\\.([[:blank:]]+|$)"

OssoH

Cita de: MinusFour en  3 Noviembre 2021, 18:01 PM
Entonces no puedes usar: [[:<:]] ni [[:>:]], porque esos caracteres consideran PATATA-FRITA como dos palabras. Podrías usar:

Código (sql) [Seleccionar]
"(^|[[:blank:]]+)DEC\\.([[:blank:]]+|$)"

PERFECTOOOO FUNCIONA.
MUCHAS GRACIASSSSS
;-) ;-) ;-) ;-) ;-) ;-)

el-brujo

Buscar en MySQL es un "rollo" a parte que es muy lento.

En el foro usamos el buscador Sphinx para MySQL (MariaDB) que funciona mucho más rápido.