将字段从一个字段拆分为两个字段

我有一个表字段membername名称,其中包含用户的姓氏和名字。 是否有可能分成2个字段memberfirstmemberlast

所有的logging都有这种格式的“名字姓氏”(没有引号和之间的空格)。

不幸的是,MySQL不具有拆分stringfunction。 但是,您可以为此创build一个用户定义的函数 ,如下面的文章中所述:

  • MySQL分割string函数由Federico Cargnelutti

有了这个function:

 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 ; 

你将能够build立你的查询,如下所示:

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

如果您不想使用用户定义的函数,并且不介意查询更加冗长,则还可以执行以下操作:

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

如果你不想使用一个函数,这个查询处理的事情比其他答案更干净:

 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`; 

与其他答案相比, 这种方法需要处理:

  • 没有空格的成员名称:它会将整个string添加到memberfirst,并将memberlast设置为NULL。
  • 具有多个空格的成员名称 :它将在memberfirst的第一个空格之前添加所有内容,其余部分(包括额外的空格)将添加到memberlast。

UPDATE版本将是:

 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 ); 

如果您的计划是将这作为查询的一部分要这样做(a) 。 严重的是,这是一个性能杀手。 在某些情况下,你不关心性能(例如一次性迁移工作来拆分字段,以便将来可以获得更好的性能),但是如果您经常为除mickey-mouse数据库以外的任何其他工作而进行此操作,那么您浪费资源

如果您发现自己不得不以某种方式只处理某一列的一部分,那么您的数据库devise是有缺陷的。 它可能在家庭地址簿或配方应用程序或任何其他小型数据库的任何工作正常,但它不会扩展到“真实”的系统。

将名称的组件存储在单独的列中。 通过一个简单的连接(当你需要全名时)连接列几乎总是快得多,而不是通过一个字符search来拆分它们。

如果由于某种原因,你不能拆分字段,至less要放入额外的列,并使用插入/更新触发器来填充它们。 虽然不是3NF,这将保证数据仍然是一致的,将大大加快您的查询。 你也可以确保额外的列是小写(如果你正在search索引的话),这样就不必在案例问题上摆弄。

而且,如果你甚至不能添加列和触发器,请注意(如果是客户端的话,让你的客户端知道它不可扩展)。


(a)当然,如果你的意图是使用这个查询来修复这个模式,以便这个名字被放在表中的不同列中而不是查询中,我会认为这是一个有效的用法。 但我重申,在查询中这样做并不是一个好主意。

用这个

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

不完全回答这个问题,但面对同样的问题,我结束了这样做:

 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 

唯一的情况下,你可能需要这样的function是一个更新查询,这将更改您的表来存储名字和姓氏到单独的字段。

数据库devise必须遵循一定的规则, 数据库规范化是最重要的

现有的答复似乎过于复杂或不是对特定问题的严格回答。

我认为,简单的答案是以下查询:

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

我认为在这种特殊情况下,没有必要处理两个以上的单词。 如果你想正确地做,分裂可能是非常困难的,甚至在一些情况下是不可能的:

  • 埃德加· 爱伦 ·
  • 约翰·沃尔夫冈·冯·歌德
  • 雅各布·路德维希·费利克斯· 门德尔松 – 巴托尔迪
  • Lea Mendelssohn Bartholdy
  • 裴多菲 ·
  • 黒泽

在一个devise合理的数据库中,应该把人名分别存储和整体存储。 当然这并不总是可能的。

我有一列名字和姓氏都在一列。 名字和姓氏之间用逗号隔开。 下面的代码工作。 没有错误检查/更正。 只是一个愚蠢的分裂。 使用phpMyAdmin来执行SQL语句。

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

13.2.10更新语法

这需要从这里smhg和curt从MySQL中给定的子string的最后索引,并结合起来。 这是用于mysql的,我所需要的就是将姓氏的名字拆分成first_name last_name,其姓氏是单个单词,第一个名称是单个单词之前的所有内容,其中名称可以是null,1个单词,2个单词或超过2个字。 即:空; 玛丽; 玛丽·史密斯 玛丽A.史密斯; Mary Sue Ellen Smith;

所以如果名字是一个单词或null,那么last_name是空的。 如果名字大于1个单词,则last_name是最后一个单词,first_name是最后一个单词之前的所有单词。

请注意,我已经削减了像乔·史密斯这样的东西。 乔·史密斯Esq。 等等,手动,这当然是痛苦的,但它足够小,所以你要确保在确定使用哪种方法之前真正查看名称字段中的数据。

请注意,这也会削减结果,所以您不会在名称前面或后面留下空格。

我只是发布这个为其他人可能谷歌他们的方式在这里寻找我需要的东西。 这个工作,当然,先selecttesting它。

这是一回事,所以我不在乎效率。

 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 ) ); 

当数据全部到达first_name字段时,用于将first_name分割为first_name和last_name的方法。 这只会把最后一个字放在姓氏字段中,所以“john phillips sousa”将是“john phillips”的名字和“sousa”的姓氏。 它也避免了覆盖已经被修复的logging。

 set last_name=trim(SUBSTRING_INDEX(first_name, ' ', -1)), first_name=trim(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(trim(last_name))=0 
 UPDATE `salary_generation_tbl` SET `modified_by` = IF( LOCATE('$', `other_salary_string`) > 0, SUBSTRING(`other_salary_string`, 1, LOCATE('$', `other_salary_string`) - 1), `other_salary_string` ), `other_salary` = IF( LOCATE('$', `other_salary_string`) > 0, SUBSTRING(`other_salary_string`, LOCATE('$', `other_salary_string`) + 1), NULL ); 

MySQL 5.4提供了一个本地分割函数:

 SPLIT_STR(<column>, '<delimiter>', <index>)