0

我们有一个技术支持代理搞砸了,不小心在我们的“全名”列中删除了第一个中间名和姓氏之间的空格。

所以而不是

John Alan Smith

读到的名字

JohnAlanSmith

我们没有单独列中的名称,也没有其他名称来源。这是针对第三方应用程序。

我们的数据库中有 1500 多个用户,因此我们需要轻松地纠正这个问题。我能想到的唯一方法是检测大写字母。当然,我们需要以某种方式排除姓氏中间的大写字母,例如 McDonald 等。

我们可以发出一条 SQL 语句来执行此操作吗?即使我们只需要手动更正 100 个名称,它也比 1500+ 好。

4

3 回答 3

1

我忍不住尝试了这个。以下代码适用于 SQL Server,它确实有效(您可以在 sqlfiddle 上查看)。

这是一个多步骤的过程。这个想法是通过加入一堆数字并检查字符的值来确定名称中每个大写字母的位置,以查看它是否大写。每个大写字母都在自己的行中。

然后,为此提取名称部分并将每个字符串的字符串连接在一起。此方法有效,假设第一个字母大写(如果不是这种情况,很容易修复)。

另外,请记住一些大写字母不是“边缘”:“McGarvey”、“Chen-Smith”等等。

这些步骤中的每一个都将因数据库而异。

with somenums as (
      select 1 as n union all select 2 union all select 3 union all select 4 union all select 5
     ),
     nums as (
      select ROW_NUMBER() over (order by (select NULL)) as n
      from somenums s cross join somenums s2
     ),
     test as (
         select 'JohnAlanSmith' as name union all
         select 'MaryElizabethChou'
     ),
     caps as (
      select name, n
      from test join
           nums
           on ascii(SUBSTRING(test.name, nums.n, 1)) between ascii('A') and ascii('Z')
    ),
    nameparts as (
     select name, n, nextn, SUBSTRING(name, n, coalesce(nextn - n, 1000)) as namepart
     from (select name, n,
                  (select min(n) from caps c2 where c2.name = c.name and c2.n > c.n
                  ) as nextn
           from caps c
          ) c
    )
select name,
       STUFF((select ' '+namepart
              from nameparts np2
              where np2.name = np.name
              order by n
              for xml path ('')
             ), 1, 1, ''
            ) as betterName
from nameparts np
group by name
于 2013-04-01T22:13:21.587 回答
0

对于 MySQL:

当您不想浪费太多时间编写复杂的函数时,您可以尝试以下方法:

/*test data*/
create table foo(name varchar(50));
insert into foo values ('JohnAndySmith');

select
name,
trim(replace(replace(name, 'A', ' A'), 'S', ' S'))
from
foo

看到它住在这里

当然,您必须对整个字母表都这样做。该TRIM()函数删除第一个字母前面的空格。

有关我使用的功能的更多信息,请参阅手册

于 2013-04-01T22:12:04.150 回答
0

根据您的 RDBMS,这样的事情可能会起作用。这专门用于 SQL Serer,并使用一个函数,该函数接受字符串中的字段和位置并返回字符串直到下一个大写字母:

select field, fname, mname, dbo.ReturnCapString(field,len(fname)+len(mname)+1) lname
from
  (
    select field, fname, dbo.ReturnCapString(field,len(fname)+1) mname
    from
      (
      select field, dbo.ReturnCapString(field,1) fname
      from yourtable
        ) t
    ) t2

而函数——函数的主要内容是ASCII检查字符是否为大写:

CREATE FUNCTION ReturnCapString (@String VARCHAR(100), @Pos int) 
RETURNS varchar(100)
AS 
BEGIN 
   DECLARE @return varchar(100) 
   DECLARE @position INT 
   DECLARE @counter INT 

   SET @position = @Pos + 1
   SET @counter = 1
   SET @return = ''

   WHILE @position <= DATALENGTH(@string) AND @return = ''
   BEGIN 
       IF ASCII(SUBSTRING(@string, @position, 1)) BETWEEN 65 AND 90  
           SELECT @return = SUBSTRING(@string, @pos, @counter)

       SET @position = @position + 1 
       SET @counter = @counter + 1 

   END 

   IF @return = '' 
   BEGIN
     SET @return = SUBSTRING(@String, @Pos, LEN(@string))
   END 

   RETURN @return 
END

当然,还有要演示的SQL Fiddle 。

顺便说一句——感谢您提出有趣的问题!虽然这并不完美(不要认为任何事情都会 100% 完美)如果您需要潜在地标记任何明显的问题,请使用此小提琴:http ://sqlfiddle.com/#!3/77f446/10

FLAG   FIELD            FNAME    MNAME    LNAME
       JohnAlanSmith    John     Alan     Smith
       McDonalds        Mc                Donalds
X      JimBobMacDonald  Jim      Bob      Mac
于 2013-04-01T22:25:30.130 回答