【问题标题】:Isolate names from a combined name cell in SQL从 SQL 中的组合名称单元格中分离名称
【发布时间】:2018-07-30 12:38:05
【问题描述】:

我正在尝试使用 substring、instr 和 charindex 的组合,以始终如一地从组合字符串值中获取名称,格式如下: "Lastname,Firstname MiddleName"

我必须能够考虑以下逻辑:

  1. 某些名称(包括名、中间名、包括最后在内)是连字符的。
  2. 除了名字和中间名之间的空格之外什么都没有。
  3. 您不必有中间名。

这是我目前所拥有的

,SUBSTRING(p.Name,1,INSTR(p.Name,',',1) - 1) as "Patient Surname"
,SUBSTRING(p.Name,INSTR(p.Name,' ',1) + 1, INSTR(p.Name,' ')) as "Patient Middle Name"  
,SUBSTRING(p.Name,INSTR(p.Name,',',1) + 1, INSTR(p.Name,' ')) as "Patient First Name"   

我也尝试过这样的事情来获得名字。

,SUBSTRING(p.Name,charindex('','',p.Name)+1, charindex(',',reverse(p.Name))) as "Patient First Name"

我似乎对姓氏很有信心。 名字和中间名是我努力捕捉的。任何人都可以帮忙吗?

这里有一些我必须使用的示例名称。

  • 熊,布布棕
  • 测试,Edis 女
  • Kgh-cdr,青色蜡笔
  • Kghcdr,Amber B
  • 猛龙队,多伦多篮下
  • Pcstest,图表审查
  • Medrec,测试人一号
  • 圣。蓝精灵,贝克
  • 水果,红味-百胜
  • 水果、青苹果苹果酱
  • 水果、青葡萄
  • ZZSivagnanasundaram,TestLongName 测试中间名
  • 鱼,蓝一号
  • 鱼,试粉
  • 蓝精灵,懒骨头
  • 水果,石榴红
  • 水果、石榴新
  • O'Fruit,Banana Too
  • 划船,划船
  • 水果,芒果秒

【问题讨论】:

  • 如果某人没有中间名怎么办?这假设他们确实......
  • 更新了该条件。谢谢!
  • 所以如果没有中间名就没有空格?您可以编写一个 CASE 并检查逗号后是否有空格,如果没有则将中间名设为 NULL
  • 在这种情况下,我的代码似乎唯一关心的是 St. Smurf,Baker - 但我想我已经通过寻找 , 字符后面的空格来解决这个问题 - 诸如连字符无关紧要,因为我不是在寻找它,它也可以使用空格和逗号以外的任何字符
  • 您尝试做的事情基本上是不可能的。一旦您为当前数据找到解决方案,就会有其他东西出现并破坏它。此外,您可能想看看这个。 kalzumeus.com/2010/06/17/…

标签: sql-server sql-server-2008 concatenation


【解决方案1】:
declare @x as varchar(100) = 'Dinsmore,Archibald Hector';

SELECT LEFT(@x, CHARINDEX(',', @x) -1 ) as surname,
                SUBSTRING(@x, 
                            CHARINDEX(',', @x) + 1, 
                            CHARINDEX(' ',  @x, CHARINDEX(',', @X)) - CHARINDEX(',', @x) - 1
                        )  as FirstName,
                        SUBSTRING(@x, 
                                  CHARINDEX(' ',  @x, CHARINDEX(',', @X)) + 1  , 
                                  CHARINDEX(' ', REVERSE(@X))) as middleName

好的,下面这个也处理中间名

declare @x as varchar(100) = 'Dinsmore,Archibald';

SELECT  CHARINDEX(' ',  @x, CHARINDEX(',', @X))

SELECT LEFT(@x, CHARINDEX(',', @x) -1 ) as surname,

                CASE WHEN CHARINDEX(' ',  @x, CHARINDEX(',', @X)) > 0 THEN
                SUBSTRING(@x, 
                            CHARINDEX(',', @x) + 1, 
                            CHARINDEX(' ',  @x, CHARINDEX(',', @X)) - CHARINDEX(',', @x) - 1
                        )  
                ELSE                            
                        RIGHT(@x, CHARINDEX(',', REVERSE(@X)) - 1)  
                END as FirstName,

                        CASE WHEN CHARINDEX(' ',  @x, CHARINDEX(',', @X)) > 0 THEN
                        SUBSTRING(@x, CHARINDEX(' ',  @x, CHARINDEX(',', @X)) + 1  , CHARINDEX(' ', REVERSE(@X))) 
                        ELSE
                          NULL
                          END   as middleName

【讨论】:

  • 如果没有中间名会中断
  • 谢谢,但我收到错误:<Invalid length parameter passed to the SUBSTRING function>
  • @frantumn 输入字符串是什么?我在 Q 中使用您的确切输入字符串进行了测试
  • @whatsthepoint - 谢谢 - 这类事情很容易受到任何奇怪数据的影响,因此任何名称中包含空格或格式错误的数据 - 都会很困难!
  • @Cato 是的,我正在测试这样的案例,但在理想情况下,您希望在进入数据库之前处理任何奇怪的事情(例如,如果您在中间名它只返回中间名的第一个字母)
【解决方案2】:

检查此代码:

declare @string varchar(500)

set @string = 'Lastname,Firstname Middlename'

declare @pos int,
        @data Nvarchar(250)
set @pos=2

set @data =(
select x.i.value('.','varchar(250)') as data 
from 
(
 select CONVERT(XML,'<i>'+REPLACE(@string,',','</i><i>')+'</i>') as data 
)x1 
cross apply data.nodes('i[position()=sql:variable("@pos")]')  as x(i))

select @data as data, 
REPLACE(@data, SUBSTRING(@data, CHARINDEX(' ', @data), len(@data)+1-CHARINDEX(' ', @data)),'') FirstName,
SUBSTRING(@data, CHARINDEX(' ', @data), len(@data)+1-CHARINDEX(' ', @data)) MiddleName

【讨论】:

    【解决方案3】:

    我想这是最简单的解决方案。我通过在末尾添加空格来使用“技巧” 然后我们只有一种情况,其中存在名字、中间名和姓氏:)

    SELECT
    B.Name, SUBSTRING(B.Name,1,CHARINDEX(',', B.Name) - 1) as "Patient Surname"
    ,SUBSTRING(B.Name,CHARINDEX(' ', B.Name + ' ') + 1, CHARINDEX(' ', B.Name + ' ')) as "Patient Middle Name"  
    ,SUBSTRING(B.Name, CHARINDEX(',', B.Name) + 1, CHARINDEX(' ', B.Name + ' ') - CHARINDEX(',', B.Name)) as "Patient First Name"  
    FROM
    (
    SELECT
    'Lastname,Firstname MiddleName' AS Name
    UNION
    SELECT
    'Lastname,Firstname' AS Name  
    ) B
    

    在 sqlfiddle 上测试 http://sqlfiddle.com/#!18/9eecb/27064/0

    更新 添加样本数据后 尤其是这个姓氏中有空格的记录

    INSERT INTO P(Name) VALUES('St. Smurf,Baker');
    

    我修改了答案

    SELECT
    P.Name, SUBSTRING(P.Name,1,CHARINDEX(',', P.Name) - 1) as "Patient Surname"
    ,SUBSTRING(P.Name, CHARINDEX(' ', P.Name + ' ', CHARINDEX(',', P.Name)) + 1, CHARINDEX(' ', P.Name + ' ', CHARINDEX(',', P.Name))) as "Patient Middle Name"  
    ,SUBSTRING(P.Name, CHARINDEX(',', P.Name) + 1, CHARINDEX(' ', P.Name + ' ', CHARINDEX(',', P.Name)) - CHARINDEX(',', P.Name)) as "Patient First Name"  
    FROM
    P
    

    您在 sqlfiddle 上的示例数据的结果 http://sqlfiddle.com/#!18/e525d/4/0

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-06
      • 1970-01-01
      • 1970-01-01
      • 2014-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多