我有一个表字段membername
,其中包含姓氏和用户的名字.是否有可能分裂成那些2场memberfirst
,memberlast
?
所有记录都具有"Firstname Lastname"格式(没有引号,中间有空格).
Dan*_*llo 221
不幸的是,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 ;
Run Code Online (Sandbox Code Playgroud)
您可以按如下方式构建查询:
SELECT SPLIT_STR(membername, ' ', 1) as memberfirst,
SPLIT_STR(membername, ' ', 2) as memberlast
FROM users;
Run Code Online (Sandbox Code Playgroud)
如果您不想使用用户定义的函数,并且您不介意查询更冗长,您还可以执行以下操作:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(membername, ' ', 1), ' ', -1) as memberfirst,
SUBSTRING_INDEX(SUBSTRING_INDEX(membername, ' ', 2), ' ', -1) as memberlast
FROM users;
Run Code Online (Sandbox Code Playgroud)
smh*_*mhg 67
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`;
Run Code Online (Sandbox Code Playgroud)
这种方法也需要注意:
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
);
Run Code Online (Sandbox Code Playgroud)
pax*_*blo 20
如果您的计划是作为查询的一部分执行此操作,请不要这样做(a).说真的,这是一个性能杀手.在某些情况下,您可能不关心性能(例如一次性迁移作业以分割字段以便将来获得更好的性能)但是,如果您经常对除米老鼠数据库之外的任何其他内容执行此操作,则'浪费资源.
如果你曾经发现自己有处理一列中的一部分以某种方式,你的数据库的设计是有缺陷的.它可能适用于家庭地址簿或食谱应用程序或任何其他无数小型数据库,但它不能扩展到"真实"系统.
将名称的组件存储在单独的列中.通过简单的连接(当您需要全名)将列与一个字符搜索分开时,将列连接起来几乎总是快得多.
如果由于某种原因你无法拆分字段,至少放入额外的列并使用插入/更新触发器来填充它们.虽然不是3NF,但这将保证数据仍然一致,并将大大加快您的查询速度.您还可以确保额外的列是低层的(并且如果您正在搜索它们,则会编入索引),以便不必处理案例问题.
而且,如果您甚至无法添加列和触发器,请注意(并让您的客户端知道,如果是客户端),它是不可扩展的.
(一)当然,如果你的目的是使用此查询到固定的模式,这样的名字被放入单独的列在表中,而不是查询,我认为这是一个有效的使用.但我重申,在查询中这样做并不是一个好主意.
Dáv*_*áth 18
现有的回答似乎过于复杂,或者对特定问题没有严格的回答.
我想,简单的答案是以下查询:
SELECT
SUBSTRING_INDEX(`membername`, ' ', 1) AS `memberfirst`,
SUBSTRING_INDEX(`membername`, ' ', -1) AS `memberlast`
;
Run Code Online (Sandbox Code Playgroud)
我认为在这种特殊情况下没有必要处理超过两个字的名字.如果你想正确地做到这一点,在某些情况下拆分可能非常困难甚至是不可能的:
在设计合理的数据库中,人名应该存储在部分和整体中.当然,这并非总是可行的.
用这个
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX( `membername` , ' ', 2 ),' ',1) AS b,
SUBSTRING_INDEX(SUBSTRING_INDEX( `membername` , ' ', -1 ),' ',2) AS c FROM `users` WHERE `userid`='1'
Run Code Online (Sandbox Code Playgroud)
小智 6
在 MySQL 中,这是使用此选项:
SELECT Substring(nameandsurname, 1, Locate(' ', nameandsurname) - 1) AS
firstname,
Substring(nameandsurname, Locate(' ', nameandsurname) + 1) AS lastname
FROM emp
Run Code Online (Sandbox Code Playgroud)
不完全回答这个问题,但面对同样的问题,我最终做到了这一点:
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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
261635 次 |
最近记录: |