【问题标题】:Split middle initial from first name in sql server从sql server中的名字拆分中间名
【发布时间】:2016-05-27 08:56:48
【问题描述】:

我希望将中间名与名字分开,只有名字有空格,空格后也应该是 1 个字符,如果它有超过 1 个字符,我们应该将整个字符串视为名字。

例如:输入字符串是“MATE K”,那么它应该分成两部分,

名字 = MATE & MiddleInitial = K

但是如果输入字符串是“MATE KATE”,那么它不应该拆分并保持原样。

名字 = MATE KATE

这是我确实工作的示例,但它没有给我预期的输出。

有人可以帮帮我吗?

declare @name as varchar(50)
set @name ='MATE KATE'
select left(@name, CHARINDEX(' ', @name)) as FirstName,
substring(@name, CHARINDEX(' ', @name) +1, len(@name)-(CHARINDEX(' ',@name)-1)) as MiddleInitial

【问题讨论】:

  • MateKATE 没有空间,您需要 Firstname as MateKate
  • @mohan111 如果输入字符串有空格,那么我们也将存储空格,例如如果输入字符串是“MATE KATE”,那么我们将在名字列中存储“MATE KATE”。
  • 如果会有M Kate
  • @gofr1 在这种情况下,我们会将 M KATE 存储为名字

标签: sql sql-server


【解决方案1】:

这不会考虑所有可能的坏字符串,但会给你一个起点。你最好不要在SQL 中这样做,而是在一些CLR 中这样做。 SQL 不应该做这样的事情,而且非常有限:

DECLARE @t TABLE ( s VARCHAR(MAX) )
INSERT  INTO @t
VALUES  ( 'MATE K' ),
        ( 'MATE KATE' )


SELECT  SUBSTRING(s, 1,
                  CASE WHEN SUBSTRING(REVERSE(s), 2, 1) = ' '
                       THEN CHARINDEX(' ', s) - 1
                       ELSE LEN(s)
                  END) AS FirstName ,
        CASE WHEN SUBSTRING(REVERSE(s), 2, 1) = ' '
             THEN SUBSTRING(s, LEN(s), 1)
             ELSE NULL
        END AS MiddleName
FROM    @t

输出:

FirstName   MiddleName
MATE        K
MATE KATE   NULL

【讨论】:

  • 如果输入中有更多空格 - 这会破坏结果。
  • @gofr1,不仅仅是空格 :) 我提到你不能考虑所有可能的情况。
  • @GiorgiNakeuri Aaa 没关系 :) 它有效,一切都很好 :)
【解决方案2】:

这应该可以完成工作,但可能可以简化:

DECLARE @name AS VARCHAR(50)
SET @name = 'MATE K'

SELECT  CASE WHEN CHARINDEX(' ', @name) != LEN(@name) - 1 THEN @name
             ELSE LEFT(@name, CHARINDEX(' ', @name))
        END AS FirstName ,
        CASE WHEN CHARINDEX(' ', @name) = LEN(@name) - 1
             THEN SUBSTRING(@name, CHARINDEX(' ', @name) + 1, 1)
             ELSE ''
        END AS MiddleName

Output:
FirstName   MiddleName
MATE        K

SET @name = 'MATE KATE'

SELECT  CASE WHEN CHARINDEX(' ', @name) != LEN(@name) - 1 THEN @name
             ELSE LEFT(@name, CHARINDEX(' ', @name))
        END AS FirstName ,
        CASE WHEN CHARINDEX(' ', @name) = LEN(@name) - 1
             THEN SUBSTRING(@name, CHARINDEX(' ', @name) + 1, 1)
             ELSE ''
        END AS MiddleName

-- Output:
    Output:
FirstName   MiddleName
MATE KATE       

【讨论】:

    【解决方案3】:
    DECLARE @t table 
    (name varchar(20))
    INSERT INTO @t(name) values 
    ('MATE K'),
    ('MATE KATE')
    
    select 
    CASE WHEN LEN(substring(name, CHARINDEX(' ', name) +1, len(name)-(CHARINDEX(' ',name)-1))) > 1 
    THEN 
    NAME 
    ELSE  left(name, CHARINDEX(' ', name)) END as FirstName,
    CASE WHEN LEN(substring(name, CHARINDEX(' ', name) +1, len(name)-(CHARINDEX(' ',name)-1))) = 1
    THEN 
    substring(name, CHARINDEX(' ', name) +1, len(name)-(CHARINDEX(' ',name)-1)) ELSE NULL END as MiddleInitial
    FROM @t
    

    【讨论】:

      【解决方案4】:

      希望这会有所帮助。

          declare @name as varchar(50)
      set @name ='MATE    K'
      select CASE WHEN CHARINDEX(' ',REVERSE(LTRIM(RTRIM(@name))),0)=2 THEN left(LTRIM(RTRIM(@name)), CHARINDEX(' ', LTRIM(RTRIM(@name))))   ELSE   LTRIM(RTRIM(@name)) END AS firstname,
      CASE  WHEN CHARINDEX(' ',REVERSE(LTRIM(RTRIM(@name))),0)=2 THEN LTRIM(RTRIM(substring(LTRIM(RTRIM(@name)), CHARINDEX(' ', LTRIM(RTRIM(@name))) +1, len(LTRIM(RTRIM(@name)))-(CHARINDEX(' ',LTRIM(RTRIM(@name)))-1))))  ELSE ''  END  as MiddleInitial
      

      【讨论】:

      • 谢谢!!!但是如果输入像这样的 MATE K 字符串,这可能会失败。也就是说,如果 MATE 和 K 之间有多个(可能是 4 或 5 个空格)空间
      【解决方案5】:

      借助 XML:

      DECLARE @name varchar(50),
              @xml xml
      
      SET @name ='Mate Kate'
      
      SELECT @xml = CAST('<f><n>' + REPLACE(@name,' ','</n><n>') + '</n></f>' as xml)
      
      ;WITH cte AS (
      SELECT  t.v.value('.','nvarchar(50)') as Names,
              CASE WHEN LEN(t.v.value('.','nvarchar(50)')) = 1 THEN 1 ELSE 0 END as LenName,
              row_number() over(order by t.v) as RowNumber
      FROM @xml.nodes('/f/n') as t(v)
      WHERE NULLIF(t.v.value('.','nvarchar(50)'),'') IS NOT NULL
      )
      
      SELECT 
          STUFF(
          (SELECT ' ' + NAMES
          FROM cte
          WHERE LenName = 0 OR (LenName = 1 and RowNumber = 1)
          FOR XML PATH('')),1,1,'') as FirstName,
          STUFF(
          (SELECT ' ' + NAMES
          FROM cte
          WHERE LenName = 1 AND RowNumber != 1
          FOR XML PATH('')),1,1,'') as MiddleInitial
      

      对于'Mate Kate'' Mate Kate '

      FirstName   MiddleInitial
      Mate Kate   NULL
      

      对于'Mate K''Mate K '

      FirstName   MiddleInitial
      Mate        K
      

      对于' M Kate ''M Kate'

      FirstName   MiddleInitial
      M Kate      NULL
      

      【讨论】:

        猜你喜欢
        • 2021-09-28
        • 1970-01-01
        • 1970-01-01
        • 2018-05-05
        • 2023-03-03
        • 1970-01-01
        • 2013-03-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多