Fractionner la valeur d’un champ à deux

J’ai un champ nom de membername qui contient à la fois le nom de famille et le prénom des utilisateurs. Est-il possible de les diviser en deux champs memberfirst , memberlast ?

Tous les enregistrements ont ce format “Prénom Nom” (sans les guillemets et un espace entre).

Malheureusement, MySQL ne dispose pas d’une fonction de chaîne divisée. Cependant, vous pouvez créer une fonction définie par l’utilisateur pour cela, telle que celle décrite dans l’article suivant:

  • Fonction MySQL Split Ssortingng par Federico Cargnelutti

Avec cette fonction:

 DELIMITER $$ CREATE FUNCTION SPLIT_STR( x VARCHAR(255), delim VARCHAR(12), pos INT ) RETURNS VARCHAR(255) DETERMINISTIC BEGIN RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos), LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1), delim, ''); END$$ DELIMITER ; 

vous pourriez construire votre requête comme suit:

 SELECT SPLIT_STR(membername, ' ', 1) as memberfirst, SPLIT_STR(membername, ' ', 2) as memberlast FROM users; 

Si vous préférez ne pas utiliser une fonction définie par l’utilisateur et que la requête ne vous dérange pas, vous pouvez également procéder comme suit:

 SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(membername, ' ', 1), ' ', -1) as memberfirst, SUBSTRING_INDEX(SUBSTRING_INDEX(membername, ' ', 2), ' ', -1) as memberlast FROM users; 

Si vous ne souhaitez pas utiliser de fonction, cette requête gère les éléments plus propres que les autres réponses:

 SELECT IF( LOCATE(' ', `membername`) > 0, SUBSTRING(`membername`, 1, LOCATE(' ', `membername`) - 1), `membername` ) AS memberfirst, IF( LOCATE(' ', `membername`) > 0, SUBSTRING(`membername`, LOCATE(' ', `membername`) + 1), NULL ) AS memberlast FROM `user`; 

Par rapport à d’autres réponses, cette approche prend en charge:

  • valeurs de nom de membre sans espace : cela appenda la chaîne entière à memberfirst et définira memberlast à NULL.
  • valeurs membre qui ont plusieurs espaces : il appenda tout avant le premier espace à memberfirst et le rest (y compris les espaces supplémentaires) à memberlast.

La version UPDATE serait:

 UPDATE `user` SET `memberfirst` = IF( LOCATE(' ', `membername`) > 0, SUBSTRING(`membername`, 1, LOCATE(' ', `membername`) - 1), `membername` ), `memberlast` = IF( LOCATE(' ', `membername`) > 0, SUBSTRING(`membername`, LOCATE(' ', `membername`) + 1), NULL ); 

Si vous envisagez de le faire dans le cadre d’une requête, veuillez ne pas le faire (a) . Sérieusement, c’est un tueur de performance. Il peut y avoir des situations où vous ne vous souciez pas des performances (par exemple, des tâches de migration ponctuelles pour fractionner les champs permettant de meilleures performances à l’avenir), mais si vous faites cela régulièrement pour une firebase database Mickey-Mouse, vous gaspiller des ressources.

Si vous ne vous trouvez jamais à traiter une partie seulement d’une colonne, votre conception de firebase database est défectueuse. Cela pourrait bien fonctionner sur un carnet d’adresses ou une application de recette ou sur une myriade d’autres petites bases de données, mais il ne sera pas extensible à de “vrais” systèmes.

Stockez les composants du nom dans des colonnes distinctes. Il est presque toujours beaucoup plus rapide de joindre des colonnes à une simple concaténation (lorsque vous avez besoin du nom complet) que de les séparer par une recherche de caractères.

Si, pour une raison quelconque, vous ne pouvez pas diviser le champ, insérez au moins les colonnes supplémentaires et utilisez un déclencheur d’insertion / mise à jour pour les remplir. Bien qu’il ne s’agisse pas de 3NF, cela garantira la cohérence des données et accélérera considérablement vos requêtes. Vous pouvez également vous assurer que les colonnes supplémentaires sont en minuscules (et indexées si vous effectuez une recherche dessus) en même temps afin de ne pas avoir à manipuler les problèmes de requête.

Et, si vous ne pouvez même pas append les colonnes et les déclencheurs, soyez conscient (et informez votre client si c’est pour un client) qu’il n’est pas évolutif.


(a) Bien sûr, si vous souhaitez utiliser cette requête pour corriger le schéma afin que les noms soient placés dans des colonnes distinctes de la table plutôt que dans la requête, je considère que cela est une utilisation valide. Mais je le répète, le faire dans la requête n’est pas vraiment une bonne idée.

Il semble que les réponses existantes soient trop compliquées ou ne constituent pas une réponse ssortingcte à la question particulière.

Je pense que la réponse simple est la suivante:

 SELECT SUBSTRING_INDEX(`membername`, ' ', 1) AS `memberfirst`, SUBSTRING_INDEX(`membername`, ' ', -1) AS `memberlast` ; 

Je pense qu’il n’est pas nécessaire de traiter des noms comportant plus de deux mots dans cette situation particulière. Si vous voulez le faire correctement, le fractionnement peut être très difficile, voire impossible dans certains cas:

  • Edgar Allan Poe
  • Johann Wolfgang von Goethe
  • Jakob Ludwig Felix Mendelssohn-Bartholdy
  • Lea Mendelssohn Bartholdy
  • Petőfi Sándor
  • 黒 澤明

Dans une firebase database correctement conçue, les noms de personnes doivent être stockés à la fois en partie et en totalité. Ce n’est pas toujours possible, bien sûr.

utilisez ceci

 SELECT SUBSTRING_INDEX(SUBSTRING_INDEX( `membername` , ' ', 2 ),' ',1) AS b, SUBSTRING_INDEX(SUBSTRING_INDEX( `membername` , ' ', -1 ),' ',2) AS c FROM `users` WHERE `userid`='1' 

Ne répondant pas exactement à la question, mais confronté au même problème, j’ai fini par le faire:

 UPDATE people_exit SET last_name = SUBSTRING_INDEX(fullname,' ',-1) UPDATE people_exit SET middle_name = TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(fullname,last_name,1),' ',-2)) UPDATE people_exit SET middle_name = '' WHERE CHAR_LENGTH(middle_name)>3 UPDATE people_exit SET first_name = SUBSTRING_INDEX(fullname,concat(middle_name,' ',last_name),1) UPDATE people_exit SET first_name = middle_name WHERE first_name = '' UPDATE people_exit SET middle_name = '' WHERE first_name = middle_name 

Le seul cas où vous voulez une telle fonction est une requête UPDATE qui modifiera votre table pour stocker Firstname et Lastname dans des champs distincts.

La conception de la firebase database doit respecter certaines règles et la normalisation de la firebase database est l’une des plus importantes

En MySQL, cette option fonctionne:

 SELECT Subssortingng(nameandsurname, 1, Locate(' ', nameandsurname) - 1) AS firstname, Subssortingng(nameandsurname, Locate(' ', nameandsurname) + 1) AS lastname FROM emp 

J’avais une colonne où le prénom et le nom de famille étaient tous les deux dans une colonne. Le prénom et le nom ont été séparés par une virgule. Le code ci-dessous a fonctionné. Il n’y a pas de vérification / correction d’erreur. Juste une division stupide. Utilisé phpMyAdmin pour exécuter l’instruction SQL.

 UPDATE tblAuthorList SET AuthorFirst = SUBSTRING_INDEX(AuthorLast,',',-1) , AuthorLast = SUBSTRING_INDEX(AuthorLast,',',1); 

13.2.10 Syntaxe UPDATE

Cela prend le smhg d’ici et celui du dernier index d’une sous-chaîne donnée dans MySQL et les combine. C’est pour mysql, tout ce dont j’avais besoin était d’obtenir une répartition correcte du nom en first_name last_name avec le nom de famille un seul mot, le prénom tout ce qui précède, où le nom pourrait être null, 1 mot, 2 mots, ou plus de 2 mots. Ie: Null; Marie; Mary Smith; Mary A. Smith; Mary Sue Ellen Smith;

Donc, si name est un mot ou null, last_name est null. Si name est> 1 mot, last_name est le dernier mot et first_name tous les mots avant le dernier mot.

Notez que j’ai déjà enlevé des trucs comme Joe Smith Jr. Joe Smith Esq. et ainsi de suite, ce qui était pénible, bien sûr, mais c’était assez petit pour le faire, donc vous devez vous assurer de bien regarder les données dans le champ du nom avant de décider quelle méthode utiliser.

Notez que cela réduit également le résultat, vous ne vous retrouvez donc pas avec des espaces devant ou après les noms.

Je ne fais que poster ceci pour les autres qui pourraient google leur chemin ici à la recherche de ce dont j’avais besoin. Cela fonctionne bien sûr, testez-le avec la sélection en premier.

C’est une chose unique, donc je me fiche de l’efficacité.

 SELECT TRIM( IF( LOCATE(' ', `name`) > 0, LEFT(`name`, LENGTH(`name`) - LOCATE(' ', REVERSE(`name`))), `name` ) ) AS first_name, TRIM( IF( LOCATE(' ', `name`) > 0, SUBSTRING_INDEX(`name`, ' ', -1) , NULL ) ) AS last_name FROM `users`; UPDATE `users` SET `first_name` = TRIM( IF( LOCATE(' ', `name`) > 0, LEFT(`name`, LENGTH(`name`) - LOCATE(' ', REVERSE(`name`))), `name` ) ), `last_name` = TRIM( IF( LOCATE(' ', `name`) > 0, SUBSTRING_INDEX(`name`, ' ', -1) , NULL ) ); 

Méthode J’avais l’habitude de séparer first_name en first_name et last_name quand les données sont arrivées toutes dans le champ first_name. Ceci mettra seulement le dernier mot dans le champ du nom de famille, donc “john phillips sousa” sera le prénom “john phillips” et le nom de famille “sousa”. Cela évite également d’écraser les enregistrements déjà corrigés.

 set last_name=sortingm(SUBSTRING_INDEX(first_name, ' ', -1)), first_name=sortingm(SUBSTRING(first_name,1,length(first_name) - length(SUBSTRING_INDEX(first_name, ' ', -1)))) where list_id='$List_ID' and length(first_name)>0 and length(sortingm(last_name))=0 
 UPDATE `salary_generation_tbl` SET `modified_by` = IF( LOCATE('$', `other_salary_ssortingng`) > 0, SUBSTRING(`other_salary_ssortingng`, 1, LOCATE('$', `other_salary_ssortingng`) - 1), `other_salary_ssortingng` ), `other_salary` = IF( LOCATE('$', `other_salary_ssortingng`) > 0, SUBSTRING(`other_salary_ssortingng`, LOCATE('$', `other_salary_ssortingng`) + 1), NULL ); 

mysql 5.4 fournit une fonction de division native:

 SPLIT_STR(, '', )