我有一个表字段membername
,其中包含用户的姓氏和名字。是否有可能分裂成那些2场memberfirst
,memberlast
?
所有记录的格式均为“名字的姓氏”(不带引号,中间还有空格)。
我有一个表字段membername
,其中包含用户的姓氏和名字。是否有可能分裂成那些2场memberfirst
,memberlast
?
所有记录的格式均为“名字的姓氏”(不带引号,中间还有空格)。
Answers:
不幸的是,MySQL不具有分割字符串功能。但是,您可以为此创建一个用户定义的函数,例如以下文章中描述的函数:
使用该功能:
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;
LENGTH
多字节安全吗?“ LENGTH(str):返回字符串str的长度,以字节为单位。多字节字符计为多个字节。这意味着对于包含五个2字节字符的字符串,LENGTH()返回10,而CHAR_LENGTH()返回5.”
SELECT变体(不创建用户定义的函数):
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版本为:
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
);
似乎现有的回答过于复杂,或者不是对特定问题的严格回答。
我认为,简单的答案是以下查询:
SELECT
SUBSTRING_INDEX(`membername`, ' ', 1) AS `memberfirst`,
SUBSTRING_INDEX(`membername`, ' ', -1) AS `memberlast`
;
我认为在这种特殊情况下,不必处理两个以上的单词。如果您想正确执行操作,则在某些情况下拆分可能会非常困难,甚至是不可能的:
在一个经过适当设计的数据库中,人名应该部分存储或全部存储。当然,这并非总是可能的。
如果您的计划是将其作为查询的一部分,请不要这样做(a)。认真地说,它是性能杀手。在某些情况下,您可能并不关心性能(例如,一次性迁移作业会拆分字段以在将来提供更好的性能),但是,如果您定期对除米老鼠数据库以外的任何事物执行此操作,则您会在浪费资源。
如果你曾经发现自己有只处理以某种方式一栏的一部分,你的数据库的设计是有缺陷的。在家庭地址簿或食谱应用程序或无数其他小型数据库中,它可能还可以正常工作,但无法扩展到“真实”系统。
将名称的组成部分存储在单独的列中。通过简单的串联(当需要全名时)将列连接在一起比通过字符搜索将列分开要快得多。
如果由于某种原因您无法拆分该字段,请至少放入多余的列并使用插入/更新触发器来填充它们。虽然不是3NF,但这将确保数据仍然一致,并会大大加快查询速度。您还可以确保多余的列同时是小写的(如果要搜索它们,则将它们编入索引),这样就不必摆弄大小写问题。
而且,如果您甚至无法添加列和触发器,请意识到(并且让您的客户端知道,如果是针对客户端的)它是不可扩展的。
(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
在MySQL中,此选项有效:
SELECT Substring(nameandsurname, 1, Locate(' ', nameandsurname) - 1) AS
firstname,
Substring(nameandsurname, Locate(' ', nameandsurname) + 1) AS lastname
FROM emp
您可能需要这种功能的唯一情况是UPDATE查询,该查询将更改表以将Firstname和Lastname存储在单独的字段中。
数据库设计必须遵循某些规则,而数据库规范化是最重要的规则之一
我有一列,名字和姓氏都在一个列中。名字和姓氏之间用逗号分隔。下面的代码有效。没有错误检查/更正。只是愚蠢的分裂。使用phpMyAdmin执行SQL语句。
UPDATE tblAuthorList SET AuthorFirst = SUBSTRING_INDEX(AuthorLast,',',-1) , AuthorLast = SUBSTRING_INDEX(AuthorLast,',',1);
这需要从此处获取smhg,并需要从MySQL中给定子字符串的Last索引获取curt并将它们组合在一起。这是针对mysql的,我所需要做的就是将名字拆分成first_name last_name,将姓氏用一个单词表示,将名字放在该单词之前的所有内容,其中名称可以为null,1个单词,2个单词或超过2个字。即:无;玛丽; 玛丽·史密斯;玛丽·A·史密斯;玛丽·苏·埃伦·史密斯(Mary Sue Ellen Smith);
因此,如果名称是一个单词或为空,则last_name为空。如果name> 1个单词,last_name是最后一个单词,并且first_name所有单词都在最后一个单词之前。
注意,我已经裁掉了小乔·史密斯(Joe Smith Jr.)之类的东西。乔·史密斯Esq。等等,当然,这是很痛苦的,但是它很小,足以做到这一点,因此,在确定使用哪种方法之前,您需要确保真正查看名称字段中的数据。
请注意,这也会修剪结果,因此您不会在名称的前面或后面最后留空格。
我只是将其发布给其他可能在这里使用google搜索我所需内容的人。当然,此方法有效,请先选择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字段中时,方法I曾经将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
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
);