在MySQL查询中实现字符串的分割和合并

4
+------+-----------------+
|  id  |      name       +
+------+-----------------+
|  1   | David Gilmour   |
|  2   | Roger Waters    |
|  3   | Li Jen Ho       |
+------+-----------------+

目前名称的格式为firstName lastName,我想将其更改为lastName firstName,而且我希望在一个数据库查询中完成。

我的解决方案是通过使用space拆分名称,翻转项目,然后再次使用space粘合。但我不知道如何编写查询。



我可以通过在 PHP 中通过空格拆分名称并将它们放入数组中,翻转数组,然后通过空格粘合单词来简单实现,但当前我无法访问 PHP。

更新 1:我发现了这个类似的问题,但我无法让它工作。我希望我没有重复提出问题。

更新 2:名称可能包含多个部分。我假设只有第一个单词是名字,其余部分是姓氏。


你有什么可用的工具呢?awk 可以在一秒钟内完成,Word 也可以通过查找替换来完成,Excel 公式也可以帮助...否则,如果你要在数据库中存储名称并且这些部分具有意义(比如“姓”和“名”),你应该保留两列以避免出现此类问题。 - lc.
我不会假设他在使用微软办公套件。标签明确指出“mysql”。他还谈到了使用PHP,这表明他正在编写服务器端的Web脚本。 - Bill N.
@lc。我正在使用的服务器只有mysql,无法在其上安装php!为“名字”和“姓氏”创建2个列是一个好主意,但我仍然在拆分名称方面遇到问题。 - Farid Rn
你能安装像 https://github.com/mysqludf/lib_mysqludf_preg#readme 这样的 MySQL 库吗? - Digital Chris
@DigitalChris 我不确定。我原以为我能找到一个简单快速的 SQL 查询来解决我的问题。 - Farid Rn
显示剩余2条评论
3个回答

5

我知道我来晚了,但有一个更好的解决方案可以处理未知数量的结果。

GROUP_CONCAT


(Group_concat是一种MySQL聚合函数,可将多个行合并为单个字符串。)
SELECT student_name,
  GROUP_CONCAT(DISTINCT test_score
               ORDER BY test_score DESC SEPARATOR ' ')
FROM student
GROUP BY student_name;

2

试试这个:

select concat(last_name," ",first_name) as FullName
from
(
select SUBSTRING_INDEX(SUBSTRING_INDEX(name, ' ', 2), ' ', -1) AS last_name, 
SUBSTRING_INDEX(SUBSTRING_INDEX(name, ' ', 1), ' ', -1) AS first_name
from your_table
) tab

在这里查看一个样例

http://sqlfiddle.com/#!2/cd4ee/4

编辑:

稍微修改一下版本就可以满足您的需求。您可以参考相同的示例来获取更新的样例。

select concat(last_name," ",first_name) as FullName
from
(
select right(name,(length(name) - instr(name,' '))) as last_name, 
SUBSTRING_INDEX(SUBSTRING_INDEX(name, ' ', 1), ' ', -1) AS first_name
from tab
) tab1

你的解决方案看起来很有前途,但我对我的问题进行了更新。名字可以由多个部分组成,我想将第一部分作为名字,其余部分作为姓氏。 - Farid Rn
2
虽然这对他指定的所有标准都有效,但如果OP希望它能够正确地扩展,他们应该考虑使索引更具动态性以支持中间名等。考虑使用LENGTH(name)-LENGTH(REPLACE(name,' ',''))来确定全名中有多少“单词”,然后相应地处理结果。 - Bill N.
我在你的示例中添加了另一行,你可以看到它运行得不好。http://sqlfiddle.com/#!2/e2b03e/1 - Farid Rn
@faridv,我暂时离开了桌子。看一下我的编辑,现在无论名称中有多少部分,它都可以正常工作了。 - Rahul
你的第二个查询似乎有效,我需要试一下。 - Farid Rn

0

这里使用三部分名称运行:http://sqlfiddle.com/#!2/e2b03e/7

SELECT 
   SUBSTRING_INDEX(SUBSTRING_INDEX(name, ' ', 1), ' ', -1) AS first_name,
   If(  length(name) - length(replace(name, ' ', ''))>1,  
   SUBSTRING_INDEX(SUBSTRING_INDEX(name, ' ', 2), ' ', -1) ,NULL) 
           as middle_name,
   SUBSTRING_INDEX(SUBSTRING_INDEX(name, ' ', 3), ' ', -1) AS last_name
from tab

在评论中,您提到想将中间名和姓氏合并到一个字段中,但不要这样做。这只会延续不良的做法,最终您肯定会以中间名等方式对姓名进行排序。

首先感谢您的回答。其次,您的答案与我在问题中提到的那个答案相同,对我并不起作用。第三,名字甚至可以超过3个部分。我需要一个涵盖任何形式给定名称的解决方案。 - Farid Rn
感谢 @Rahul 提供的 sqlfiddle 设置。 - Digital Chris
我的名字是波斯语,它们没有中间名。它们有名字和由多个部分组成的姓氏。 - Farid Rn
好的,使用上述代码并将first_name插入到一个字段中,“Middle_name Last_name”插入到另一个字段中或将其全部更新回一个名称字段中仍然没有问题,但如果可以避免,请不要这样做。 - Digital Chris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接