[Résolu] Pb de regexp avec Mysql

Pb de regexp avec Mysql [Résolu] - SQL/NoSQL - Programmation

Marsh Posté le 10-06-2021 à 12:15:12    

Bonjour,
J'ai une requête à faire en SQL et je veux pouvoir remonter les enregistrements qui ont la valeur 5 (par ex) dans leur champ "valeur". Voici un exemple d'enregistrement (le "|" indique que la valeur regroupe plusieurs valeurs sélectionnées)
5
58
3|5|10
58|3|5
2|59
1|3|55
5|26|25
5|57|55
 
J'ai fait un truc du genre select * FROM Table Where valeur REGEXP "((^5$)|(5\|)|(\|5\|)|(\|5$))". Mais ça ne plaît pas à Mysql qui me retourne  #1139 - Got error 'empty (sub)expression' from regexp.
Pourtant, sur le site https://regex101.com/, cette regexp me retourne les bons enregistrements, à sa voir le "5", le "3|5|10", le "5|26|25" et le "5|57|55". Une idée de comment faire ma regexp différemment pour rendre joyeux Mysql, svp ?
 
Merci par avance :jap:


Message édité par rufo le 10-06-2021 à 14:33:00

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 10-06-2021 à 12:15:12   

Reply

Marsh Posté le 10-06-2021 à 13:56:54    

C'est bon, j'ai trouvé :
Where valeur REGEXP "(^5$|^5\||\|5\||\|5$)"


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 10-06-2021 à 16:39:45    

Autre solution :

Code :
  1. WHERE LOCATE(CONCAT('|', 5, '|'), CONCAT('|', valeur, '|')) <> 0


 
Le 5 pouvant être remplacé par un marqueur - requête préparée - mais la modélisation serait à revoir (introduction d'une table de jointure).

Reply

Marsh Posté le 10-06-2021 à 17:20:04    

Y'a pas de pb de modélisation ;)
Il s'agit d'une table permettant de stocker des valeurs de champs qui sont ajouté aux champs natifs d'une appli par configuration. Ces champs peuvent être des dates, des chaînes, des nombres, des valeurs sélectionnés parmi une liste prédéfinie ou parmi des valeurs provenant d'autres tables de l'appli. L'ex que j'ai donné concerne un champ de type "liste à sélection multiples".
Ce type de champ est là pour répondre à des besoins ponctuels et spécifiques. Quand ce sont des relations de données que l'appli doit gérer nativement, je fais bien des tables avec des relations 0-n ou n-n et des belles jointures ;)
 
Edit : merci pour ta proposition, je regarderai ce que ça donne. :)


Message édité par rufo le 10-06-2021 à 17:20:37

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 13-06-2021 à 04:11:51    

Citation :

Pourtant, sur le site https://regex101.com/, cette regexp me retourne les bons enregistrements, à sa voir le "5", le "3|5|10", le "5|26|25" et le "5|57|55". Une idée de comment faire ma regexp différemment pour rendre joyeux Mysql, svp ?

58|3|5 est aussi un bon enregistrement.
La regexp suivante devrait faire le taf :  "(^|\|)5($|\|)"
Mais si c'est du MySQL, il faut peut être doubler les \ si j'en crois la doc en ligne : "(^|\\|)5($|\\|)"
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 13-06-2021 à 10:26:48    

Oui, je te confirme que 58|3|5 est aussi un enregistrement à remonter et qu'il faut bien doubler les \\ devant certains |. Je l'ai pas mis là histoire de se concentrer juste sur le regexp ;)
Je testerai demain ta regexp qui devrait aller effectivement. Bizarrement, j'avais jamais penser que pouvais mettre un | avec un ^ ou $ mais uniquement avec des expressions "complètes".
Merci :jap:


Message édité par rufo le 13-06-2021 à 10:26:59

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 15-06-2021 à 18:47:06    

Coucou Rufo,
 
en recherchant par le Type numérique , et qui  contient la valeur 5;
" le Type numérique ; avec la valeur 5 "
 
 
============================
en Sql , tu a aussi les "sous-requetes", ou "requetes imbriquées" :
 
requete A ( utilise requete B );
 
 
utiliser une sélection , qui sera 'critère/liste de résultat' pour constituer une autre requete.
 
 select colonne-1 from table where champ = (
 select colonne from table__ where champ like '%6%' )
 AND champ_2 = 'autre critere';
 
le LIKE :
 
_  : 1 caractères
% : n caractères
 
pour de la sélection de chaine, et de caractères dans une chaine.
ça marches.
 
ex :
 
__U%  : le 3 éme caractère doit etre un U , pour une longueur indeterminé ( c'est LIKE ... on approche les critères , ils sont moins stricts..   )
pour du strict , et rigide :  champ = "chaine" , c'est tout bon.
 
c'est LIKE qui permet d'utiliser les caractères  _  et  %  ( 1 ou plusieurs caractères ).
 
tous les mots commençant par STB
...champ_3 LIKE 'STB%'
 
 
tous les mots contenant la lettre B au 10éme caractère, et finissant par 'AAA'.
champ LIKE '____________B%AAA';  
 
 


---------------
Nom : Prénom : Age : Adresse : Ville : Code Postal : Num Trois Tel
Reply

Marsh Posté le 15-06-2021 à 18:57:53    

Heu, t'es gentil, mais ça fait plus de 20 ans que je fais du SQL alors tu penses bien que les solutions à base LIKE ou de sous-requête, je connais un peu  :whistle:  
Si je suis passé par une regexp, c'est parce que je n'avais pas d'autre solution plus basique qui fonctionne correctement.
Si tu fais un like "%5%", ça va me remonter tous les enregistrement ayant un 5 dans leur valeur (ex : 15, 53, 55...) mais pas la valeur exacte 5. Je te rappelle que le champ contenant la valeur est de type VARCHAR et pas de type numérique du fait que le champ est configuration et que ça peut être une date, un nombre, une texte, une sélection simple ou multiple dans une liste.
Bien évidemment, la valeur 5 est un ex, ça peut être la valeur 35, 42, 3, 127...  
Bref, tout ça pour dire que ta proposition n'est pas une solution qui marche contrairement à celle que j'ai trouvée ou la proposition de Gilou.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 15-06-2021 à 22:36:48    

désolé Rufo  ;)

 

j'écris pas toujours une réponse directement pour la question.
C'est "complémentaire" ... selon mon humeur.

 

Jean Fromage, dans une publicité disait "A votre guise".

 

une regExp,
c'est d'abord une boucle,
puis une recherche de 'motif' : un ou un ensemble de caractère ( des symboles binaires ),
selon l'instruction choisie / replace / inString / CountOccurs ...
ça retourne les motifs trouvés dans l'ensemble determiné,
les remplaces , ou ça les comptent.

 

c'est    " for ( i = 0 ; <Type T>[ i ] ; i++ ){ if ( .... ) } return false|trouvaille[..];  "

 

et c'est pour ça que j'abordé la sous-requete
je cherchais le pattern à faire par des if ( ) successifs .. mais ça retombait sur substring ... là j'ai bug ...
une regexp ça fait substtring(substring(substring(....)))  
et le motif d'expression régulière fournit un raccourci de syntaxe forcèment trés pratique.

 

Pour une requete ou seuls un caractère est recherché "5" , je suis retombé la dessus.
vraiment pardon.

 


sur des VARCHAR tu peux regExp des entiers ,  comme il s'agit de numérique / ou d'alphanumérique.
Le parcours se fait par tronçons de la chaine totale , on peut dire qu'il va commencer par un caractère, puis le deuxieme,
et en cas de Match , il prendra le 'bon' caractère, puis ajoutera un deuxième caractère..
Le varchar ( 255 caractère ?? )  , ou une un type TEXT ( structure chainée de varchar ... 65536 ?? ) ne mettra pas en échec une Regexp sur des entiers.
L'ascii aussi.  


Message édité par djinto le 15-06-2021 à 23:14:42

---------------
Nom : Prénom : Age : Adresse : Ville : Code Postal : Num Trois Tel
Reply

Marsh Posté le 15-06-2021 à 22:57:20    

Pas de souci.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 15-06-2021 à 22:57:20   

Reply

Marsh Posté le 16-06-2021 à 01:59:44    

tiens rufo,
regarde la fonction trim de mysql

 

https://dev.mysql.com/doc/refman/8. [...] ring-index

 

pour enlever des caractères , des séparateurs ...

 


SELECT DISTINCT( TRIM( BOTH ' ','|','||' FROM 'la_colonne' )) AS 'rendu'
FROM table
WHERE la_colonne LIKE '%5%'
GROUP BY 'rendu'
ORDER BY rendu asc ;

 


souvent un critère unique est un début... dans le Trim par exemple Trim ( BOTH 1, 2, (^3, 4)  FROM '...........' )
avec une virgule , on peut ajouter des motifs RegExp , des tableaux de contenus ... pleins de choses , il faut essayer pour en être sur.
[ c'est des ressources , mais elles sont au dela du tuto ... ]

 


Donc sur les résultats de la requete , un Trim est appliqué,
et le trim va enlever les |   ||  .. et les espaces vides ..
et le distinct va éclater les 'tronçons' , dans une nouvelle colonne appellée 'rendu' .
// distinct ( Trim ( ça fait un split(tableau , separ ) );

 


donc la fonction Trim :
BOTH : avant et après la chaine.
LEADING : c'est que au début de la chaine ( le header )
TRAILING : c'est que sur la fin de la chaine ( le footer , la queue , la traine .. )

 


Message édité par djinto le 16-06-2021 à 02:27:23

---------------
Nom : Prénom : Age : Adresse : Ville : Code Postal : Num Trois Tel
Reply

Marsh Posté le 16-06-2021 à 08:32:49    

Tes bidouilles ne marcheront pas avec des choses du genre "12|5|45|71" et sont bien moins lisibles qu'une regexp. Il faut aussi penser à la maintenabilité du code.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 16-06-2021 à 08:58:19    

rufo a écrit :

Tes bidouilles ne marcheront pas avec des choses du genre "12|5|45|71" et sont bien moins lisibles qu'une regexp. Il faut aussi penser à la maintenabilité du code.

 

tu es sympathique, mais en SQL un peu de trop.

 

tu me dira d'un motif à l'autre lequel est le plus lisible :
un entier | une regexp

 

et en 'cycle-machine' :
lire un entier ,  ou 'exploiter un regexp' ( new pattern / new regexp / init boucle , if if if (log N² )

 

rien qu'à la lecture :
6,7,8  ou  regexp((^{0-9}-[Aa-Wc])) et une norme {par language}

 

tu a pas compris voila tout.

 

et oui, les ordis ça bidouilles, c'est com'pute.

 


et comme il s'agissait d'optimisation,
le trim , qui selectionnes aussi bien qu'un regExp une chaine de caractère,
a , dans MySql , des facilités redoutables.

 

dont l'utilisation de tableau, ou de série de valeurs grâce aux séparateurs ","
chiffre 1   ,   nombre 1 , tableau 2 ... etc ...

 

trim( BOTH "série à trouver juste là"  from source-totale )
série à trouver == "1,3,45,87,89"

 

Rufo, tu es une machine à apprendre plutôt tétue.
MySQL est trés puissant.
Je voulais exploiter une autre solution bien sentie.
Chacun fait comme il veut, affirmer le contraire est dangereux.

 

( Merci de ta réponse )

 

c'est aussi du code mis à plat : lean code,
c'est de la restructuration de code, tant que ça optimise les lignes de codes,
c'est une façon de refactoriser,

 

si tu utilises des ressources, alors que tu peux le faire autrement sans cette ressource.
tu va sur un gain , en lisibilité , en nombre totale de lignes de codes aussi, c'est de la célérité, de la vitesse.

 

exemple :
i++;
ou
i=i+1;
ou
while(i-1<i){
i = i + 0.00001;
}

 


le nombre d'opérations, et de cycle machine sera
sur un nombres d'instructions nécessaires complètement différent...
au développeur de mettre la 'plus rapide/ plus courte / plus efficace' dans son code,
plutot que les autres solutions.

     


Message édité par djinto le 16-06-2021 à 09:21:45

---------------
Nom : Prénom : Age : Adresse : Ville : Code Postal : Num Trois Tel
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed