我有一个表字段membername
,它包含用户的姓氏和名字。是否有可能将这些分成两个字段memberfirst
,memberlast
?将字段拆分为一个字段
所有的记录都有这种格式的“名字姓氏”(没有引号和中间的空格)。
我有一个表字段membername
,它包含用户的姓氏和名字。是否有可能将这些分成两个字段memberfirst
,memberlast
?将字段拆分为一个字段
所有的记录都有这种格式的“名字姓氏”(没有引号和中间的空格)。
不幸的是,MySQL不具备分割字符串功能。然而,你可以创建一个user defined 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 ;
你就可以建立您的查询如下:
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;
,你可能希望这样的功能的唯一情况是一个UPDATE查询,它将改变你的表来存储Firstname和Lastname到不同的字段。
数据库设计必须遵循一定的规则,Database Normalization是最重要的中
使用本
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(`membername` , ' ', 2),' ',1) AS b,
SUBSTRING_INDEX(SUBSTRING_INDEX(`membername` , ' ', -1),' ',2) AS c FROM `users` WHERE `userid`='1'
你能解释一下吗? – commonpike 2012-04-13 10:53:24
这将从字段中获取第一个和最后一个空格分隔的子字符串,这在任何情况下都不起作用。例如,如果姓名字段是“Lilly von Schtupp”,那么您将得到'Lilly','Schtupp'作为姓,姓。 – 2012-07-02 20:32:36
如果你的计划是做到这一点的查询的一部分,请不要” t那么做(a)。严重的是,这是一个性能杀手。在某些情况下,您不关心性能(例如一次性迁移作业将字段拆分,以便将来可以获得更好的性能),但是,如果您经常为除米老鼠数据库以外的任何其他目的执行此操作,则您浪费资源。
如果你有有史以来发现自己不得不以某种方式处理某一列的一部分,你的数据库设计是有缺陷的。它可能适用于家庭地址簿或配方应用程序或任何其他小型数据库,但它不会扩展到“真实”系统。
将名称的组件存储在单独的列中。通过一个简单的连接(当你需要全名时)连接字段几乎总是快得多,而不是通过字符搜索将它们分开。
如果出于某种原因无法拆分字段,至少应放入额外的列并使用插入/更新触发器来填充它们。虽然不是3NF,但这将保证数据仍然一致,并将大大加快查询速度。您还可以确保额外的列在同一时间是较小的(并且如果您正在搜索它们,则编入索引),从而无需摆弄案件问题。
而且,如果您甚至无法添加列和触发器,请注意(并且让您的客户端知道,如果它是针对客户端的)它不可伸缩。
(一)当然,如果你的目的是使用该查询修复架构,以便名字被放入单独的列在表而非查询,我认为这是一个有效的用途。但我重申,在查询中这样做并不是一个好主意。
有时候,你必须这样做。 F.E.我需要一个移植脚本,所以我不关心表演。 – 2013-11-05 11:13:10
你甚至读过这个问题吗? – dfmiller 2014-09-11 16:17:12
@dfmiller,是的,我做了,因此我的理由和详细的回应,并感谢您的兴趣。如果你对我写的东西有特定的问题,请指出,我会看看它是否可以改进。如果这确实是你的意图,那么你现在的评论对于改善情况几乎没有用处。或者,也许你只是在网上发布随机评论,很难说:-)我支持答案,当然,分栏访问是不可扩展的,几乎总是一个坏主意,除非它用于实际上是_fixing_分栏访问。 – paxdiablo 2014-09-12 01:47:26
不完全回答这个问题,而是面临着同样的问题,我最后做的:
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
如果你不想使用的功能,此查询处理的事情比清洁其他答案:
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`;
相比其他答案这种方法需要照顾:
更新版本将是:
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
);
的MySQL 5.4提供了一个天然的分割功能:
SPLIT_STR(<column>, '<delimiter>', <index>)
您能否提供文档链接? dev.mysql.com的搜索结果变干了。 12.5节在这个功能的评论中确实有一个社区建议。 – DRaehal 2013-07-02 22:21:09
我有一列,其中第一和最后一个名字是两人都在一列。名字和姓氏之间用逗号隔开。下面的代码工作。没有错误检查/更正。只是一个愚蠢的分裂。使用phpMyAdmin来执行SQL语句。
UPDATE tblAuthorList SET AuthorFirst = SUBSTRING_INDEX(AuthorLast,',',-1) , AuthorLast = SUBSTRING_INDEX(AuthorLast,',',1);
这需要从这里生硬的smhg从Last index of a given substring in MySQL,并结合他们。这是用于mysql的,我所需要的只是将姓氏的名称拆分为first_name last_name,姓氏单个单词,第一个名称在单个单词之前,名称可以为null,1个单词,2个单词或超过2个字。即:空;玛丽;玛丽史密斯;玛丽A.史密斯;玛丽苏埃伦史密斯;
因此,如果名称是一个单词或null,则last_name为空。如果名字大于1个单词,则last_name是最后一个单词,first_name是最后一个单词之前的所有单词。
请注意,我已经削减了像乔史密斯这样的东西;乔史密斯Esq。等等,手动,这当然是痛苦的,但它足够小,所以你想在确定使用哪种方法之前确保真正查看名称字段中的数据。
请注意,这也会削减结果,所以您不会在名称前面或后面出现空格。
我只是发布此为其他人可能谷歌他们的方式在这里寻找我需要什么。这当然有效,首先用select对它进行测试。
这是一次性的事情,所以我不在乎效率。
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”的姓氏。它还避免覆盖已经修复的任何记录。
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
似乎现有的答案是过于复杂或不是对特定问题的严格答案。
我认为,答案很简单,下面的查询:
SELECT
SUBSTRING_INDEX(`membername`, ' ', 1) AS `memberfirst`,
SUBSTRING_INDEX(`membername`, ' ', -1) AS `memberlast`
;
我认为这是没有必要应对这种特殊情况下更比双字名。如果你想要做正确的,拆分可以在某些情况下是非常困难甚至是不可能的:
在设计合理的数据库,人的名字应该被同时存储在零部件和整体。当然,这并非总是可行的。
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
);
“所有记录都有这种格式的”名字姓氏“(不带引号和中间的空格)。” ......奇迹般......请**请**,在做数据库决策时不要忘记像我这样的人。我经常收到网站告诉我,我的姓氏包含一个*非法*(原文如此)的字符...... :( – 2016-06-02 18:53:26
@StijndeWitt你是对的,但是看起来这个数据库似乎不包含你的名字,至少不是在我的国家姓是先写的,所以我也应该在这个数据表中“歧视”,看到这个 - > – 2018-02-07 15:55:25