在SQL中将单个列(名称)拆分为两个(forename,surname)

时间:2013-12-02 09:03:11

标签: mysql sql

目前我正在进行数据库重新设计项目。该项目的大部分内容是从旧数据库中提取数据并将其导入新数据库。

旧数据库表中的一列称为“名称”。它在一个字段中包含一个forename和一个姓氏( ugh )。新表有两列;姓氏和姓氏。我需要提出一种干净,有效的方法将这一列拆分为两个。

现在,我想在同一张桌子上做所有事情,然后我就可以轻松地将其转移。

3列:

  • 姓名(姓名和姓氏)
  • Forename(目前为空,名称的前半部分应该在这里)
  • 姓氏(目前是空的,名字的后半部分应该在这里)

我需要做什么:将名称分成两半并放入姓氏和姓氏

如果有人能说明如何做这种事情,我会非常感激,因为我之前没有在SQL中做过这样的事情。

数据库引擎:MySQL
存储引擎:InnoDB

8 个答案:

答案 0 :(得分:15)

快速解决方案是使用SUBSTRING_INDEX获取第一个空格左侧的所有内容,以及第一个空格后的所有内容:

UPDATE tablename
SET
  Forename = SUBSTRING_INDEX(Name, ' ', 1),
  Surname = SUBSTRING_INDEX(Name, ' ', -1)

请参阅小提琴here。它并不完美,因为名称可能有多个空格,但它可以是一个很好的查询,它适用于大多数名称。

答案 1 :(得分:2)

试试这个:

insert into new_table (forename, lastName, ...)
select
  substring_index(name, ' ', 1),
  substring(name from instr(name, ' ') + 1),
  ...
from old_table

这假定第一个单词是forename,其余的是lastname,它正确处理多字的姓氏,如“John De Lacey”

答案 2 :(得分:1)

对于想要处理全名的人:John - > firstname:John,lastname:null

SELECT 
if( INSTR(`name`, ' ')=0, 
    TRIM(SUBSTRING(`name`, INSTR(`name`, ' ')+1)), 
    TRIM(SUBSTRING(`name`, 1, INSTR(`name`, ' ')-1)) ) first_name,
if( INSTR(`name`, ' ')=0, 
    null, 
    TRIM(SUBSTRING(`name`, INSTR(`name`, ' ')+1)) ) last_name

它适用于John Doe。但是,如果用户只填写没有姓氏的John,则SUBSTRING(name, INSTR(name, ' ')+1)) as lastname将返回John而不是null,而SUBSTRING(name, 1, INSTR(name, ' ')-1)将使用firstname为空。

在我的情况下,我添加了条件检查以正确确定姓氏和修剪以防止它们之间存在多个空格。

答案 3 :(得分:0)

我遇到了类似的问题,但名称包含多个名称,例如。 " FirstName MiddleNames LastName"它应该是" MiddleNames"而不是" MiddleName"。

所以我使用了substring()和reverse()的组合来解决我的问题:

select 
    SystemUser.Email, 
    SystemUser.Name, 
    Substring(SystemUser.Name, 1, instr(SystemUser.Name, ' ')) as 'First Name',
    reverse(Substring(reverse(SystemUser.Name), 1, instr(reverse(SystemUser.Name), ' '))) as 'Last Name',

我不需要" MiddleNames"部分也许这不是最有效的解决方法,但它对我有用。

答案 4 :(得分:0)

来自谷歌,并提出了一个稍微不同的解决方案,它可以处理超过两个部分的名称(最多5个名称部分,由空格字符创建)。这将last_name列设置为“first name”(第一个空格)右侧的所有内容,它还将full_name设置为第一个名称部分。也许在运行之前备份你的数据库:-)但这里它对我有用:

UPDATE users SET
 name_last = 	
 CASE
 WHEN LENGTH(SUBSTRING_INDEX(full_name, ' ', 1)) = LENGTH(full_name) THEN ''
 WHEN LENGTH(SUBSTRING_INDEX(full_name, ' ', 2)) = LENGTH(full_name) THEN SUBSTRING_INDEX(del_name, ' ', -1)
 WHEN LENGTH(SUBSTRING_INDEX(full_name, ' ', 3)) = LENGTH(full_name) THEN SUBSTRING_INDEX(del_name, ' ', -2)
 WHEN LENGTH(SUBSTRING_INDEX(full_name, ' ', 4)) = LENGTH(full_name) THEN SUBSTRING_INDEX(del_name, ' ', -3)
 WHEN LENGTH(SUBSTRING_INDEX(full_name, ' ', 5)) = LENGTH(full_name) THEN SUBSTRING_INDEX(del_name, ' ', -4)
 WHEN LENGTH(SUBSTRING_INDEX(full_name, ' ', 6)) = LENGTH(full_name) THEN SUBSTRING_INDEX(del_name, ' ', -5)
ELSE ''
END,
full_name = SUBSTRING_INDEX(full_name, ' ', 1)
WHERE LENGTH(name_last) = 0 or LENGTH(name_last) is null or name_last = ''

答案 5 :(得分:0)

SUBSTRING_INDEX在SQL 2018中对我不起作用,因此我使用了它:

declare @fullName varchar(50) = 'First Last1 Last2'
declare @first varchar(50)
declare @last varchar(50)

select @last = right(@fullName, len(@fullName)-charindex(' ',@fullName, 1)), @first = left(@fullName, (charindex(' ', @fullName, 1))-1);

收益@ first ='First',@ last ='Last1 Last2'

答案 6 :(得分:0)

这将改善给出的答案,请考虑使用“ Jack Smith Smithson”这样的条目,如果您只需要姓氏和名字,并且您希望名字为“ Jack Smith”和姓氏“ Smithson”,那么您需要这样的查询:

-- MySQL

SELECT 
    SUBSTR(full_name, 1, length(full_name) - length(SUBSTRING_INDEX(full_name, ' ', -1)) - 1) as first_name, 
    SUBSTRING_INDEX(full_name, ' ', -1) as last_name 
FROM yourtable

答案 7 :(得分:-1)

只是想分享我的解决方案。它也适用于中间名。中间名将添加到名字。

SELECT 
TRIM(SUBSTRING(name,1, LENGTH(name)- LENGTH(SUBSTRING_INDEX(name, ' ', -1)))) AS firstname, 
SUBSTRING_INDEX(name, ' ', -1) AS lastname