从 SQL Server 中的名称字符串中获取中间名和名字

Posted

技术标签:

【中文标题】从 SQL Server 中的名称字符串中获取中间名和名字【英文标题】:Get middle name and first name from name string in SQL Server 【发布时间】:2014-05-01 04:39:56 【问题描述】:

我有这样的场景

Kumar, Anand 
S,Anand D
D,Ravi,K

现在,我必须使用一个查询从 SQL Server 中的上述场景中提取名字、中间名和姓氏。因为,从全名中获取中间名很难并且与名字相同,所以我尝试了

select 
   CASE 
      WHEN CHARINDEX(' ', REVERSE('D,Ravi,K')) = 0 
        THEN RIGHT('D,Ravi,K', CHARINDEX(',', REVERSE('D,Ravi,K')) - 1) 
      WHEN CHARINDEX(' ', REVERSE('D,Ravi,K')) > 0 
        THEN RIGHT('D,Ravi,K', CHARINDEX(' ', REVERSE('D,Ravi,K')) - 1)
   END AS 'MIDDLE NAME'

但是,我遇到了错误

消息 536,第 16 级,状态 1,第 1 行 传递给正确函数的长度参数无效。

谁能帮我解决这个问题?

任何其他技术都可以提取上述值。

【问题讨论】:

您需要名字、中间名和姓氏作为 3 个差异列吗?对于数据Kumar, Anand,Anaad 是中间名还是姓氏? 是的..在三个不同的列中。 Anand 将被视为First Name 如果您正在处理/建模名称,最好成为该领域的专家。很有可能,你对名字的了解比你想象的要少。 W3C 有一篇名为 Personal names around the world 的好文章,当我第一次阅读时,它让我感到谦卑。 这个问题缺少基本信息。您的“场景”是否对每行中指定 F、L、M 的顺序做出任何假设?如果不是,则由您决定是什么使 F、L、M 成为可能,那么您肯定会在解析中出错。克里斯已经向你指出了原因。另请阅读***.com/questions/5596706/… 和***.com/questions/17455658/human-name-parsing 【参考方案1】:

您需要创建一个函数来获取字符串并将其拆分为多个部分。以下是功能概述:

CREATE FUNCTION splitNames (@name VARCHAR(500), @sep VARCHAR(1))
RETURNS @ret TABLE(idx INT IDENTITY(1,1), part VARCHAR(200))
AS
BEGIN
    WHILE(CHARINDEX(@sep, @name)>0)
    BEGIN
        INSERT INTO @ret (part)
        SELECT SUBSTRING(@name, 1, CHARINDEX(@sep, @name)-1)
        SET @name = SUBSTRING(@name, CHARINDEX(@sep, @name) + LEN(@sep), LEN(@name))
    END
    INSERT INTO @ret (part) 
    SELECT  @name
    RETURN
END

然后您可以在从其他表中读取字符串时调用它或直接传递字符串,如下所示:

SELECT f.*
FROM   TABLE_NAME n
CROSS APPLY
(
    SELECT * FROM splitNames(n.name, ',')
)f

或者

SELECT * FROM splitNames('D, Ravi, Anand', ',')

-------------------
| Idx    |  part  |
-------------------
|   1    |  D     |
-------------------
|   2    |  Ravi  |
-------------------
|   3    |  Anand |
-------------------

【讨论】:

无法在 sql 查询中使用? 不,因为您需要遍历它。不过你可以试试CTE @TheVillageIdiot 当使用, 作为分隔符时,这可以正常工作,但是如果我尝试使用像Name Mid Last 这样的字符串并将函数作为dbo.splitnames('Name Mid Last',' ') 运行,那么函数显然永远不会停止运行(我'我等了 10 分钟就放弃了)。无论如何,如果我用, 替换` `,效果会很好【参考方案2】:
SELECT 'prabhat ku sahoo'                                                                                                      AS full_name,  
  SUBSTR('prabhat ku sahoo',1,instr('prabhat ku sahoo',' ',1,1))                                                                   AS first_name,
  SUBSTR('prabhat ku sahoo',instr('prabhat ku sahoo',' ',1,1),instr('prabhat ku sahoo',' ',1,2)-instr('prabhat ku sahoo',' ',1,1)) AS middle_name,
  SUBSTR('prabhat ku sahoo',instr('prabhat ku sahoo',' ',1,2))                                                                     AS last_name
FROM dual;

【讨论】:

【参考方案3】:

我认为为每个名称创建字段是正确的:

CREATE TABLE persons_tbl
(
persons_id INT(11),
first_name VARCHAR(100),
middle_name VARCHAR(100),
last_name VARCHAR(100)
);

然后得到它:

SELECT first_name, middle_name, last_name FROM persons_tbl

【讨论】:

我没有创建新表的权限。我问的是SELECT查询...不是CREATE【参考方案4】:

发生错误是因为字符串中没有任何空格。

RIGHT('D,Ravi,K',CHARINDEX(' ', REVERSE('D,Ravi,K')) -1)

CHARINDEX 返回 BLANK 或 0。

不能为 RIGHT 函数赋予负值。

您可以使用 REPLACE() 将逗号替换为空格,以保持数据的一致性

【讨论】:

【参考方案5】:

请检查我的尝试:

declare @tbl as table(Col nvarchar(100))
insert into @tbl values
('Kumar,Anand'),
('S,Anand D'),
('D,Ravi,K'),
('Anulas')

select 
    Cola,
    FN,
    REPLACE(REPLACE(Col, ','+FN,''), LN+',','') MN,
    LN
from(
    select 
        *, 
        LEFT(Col, CHARINDEX(',', col, 1)-1) LN,
        REVERSE(LEFT(REVERSE(Col), CHARINDEX(',', REVERSE(Col), 1)-1)) FN
    from(
        select Col Cola,
        case LEN(Col)-LEN(REPLACE(Col,',','')) 
                when 0 then ',,'+Col
                when 1 then REPLACE(Col, ',',',,') 
                else Col end Col
        from @tbl
    )x
)y

【讨论】:

【参考方案6】:
DECLARE @FullName    VARCHAR(50) = 'D,Ravi,K'

SELECT SUBSTRING(@FullName, 1, CHARINDEX(',', @FullName) - 1) AS [Middle Name],
       SUBSTRING(@FullName, 
           CHARINDEX(',', @FullName) +1,
           LEN(@FullName)- CHARINDEX(',',@Fullname)-2
       ) AS [First Name]

【讨论】:

【参考方案7】:

我做到了。感谢您的帮助

    declare @name varchar(100)
    set @name='Sharma,Ravi,K'


 select CASE WHEN CHARINDEX(' ',REPLACE(@name,',',' '), CHARINDEX(' ',REPLACE(@name,',',' ')) + 1) >0 THEN
        SUBSTRING(REPLACE(@name,',',' '), CHARINDEX(' ',REPLACE(@name,',',' ')) + 1,(LEN(@name)-CHARINDEX(' ',REVERSE(REPLACE(@name,',',' '))))-CHARINDEX(' ',REPLACE(@name,',',' '))) else SUBSTRING(REPLACE(@name,',',' '), CHARINDEX(' ',REPLACE(@name,',',' ')) + 1,LEN(@name)) END AS 'FIRST NAME'
    ,CASE WHEN CHARINDEX(' ',REPLACE(@name,',',' '), CHARINDEX(' ',REPLACE(@name,',',' ')) + 1) >0 THEN SUBSTRING(REPLACE(@name,',',' '),LEN(@name)-CHARINDEX(' ',REVERSE(REPLACE(@name,',',' ')))+2,LEN(@name)) ELSE ' '
    END AS 'MIDDLE NAME'
    ,
    SUBSTRING(REPLACE(@name,',',' '), 1,CHARINDEX(' ',REPLACE(@name,',',' ')))

【讨论】:

【参考方案8】:

如果字符串是FirstName/MiddleName/LastName,这将起作用

Select

DISTINCT NAMES ,

SUBSTRING(NAMES , 1, CHARINDEX(' ', NAMES) - 1) as FirstName,

RTRIM(LTRIM(REPLACE(REPLACE(NAMES,SUBSTRING(NAMES , 1, CHARINDEX(' ', NAMES) - 1),''),REVERSE( LEFT( REVERSE(NAMES), CHARINDEX(' ', REVERSE(NAMES))-1 ) ),'')))as MiddleName,

REVERSE( LEFT( REVERSE(NAMES), CHARINDEX(' ', REVERSE(NAMES))-1 ) ) as LastName

From TABLENAME

【讨论】:

【参考方案9】:

以下是从Full_Name 获取First_NameMiddle_NameLast_Name 的方法(用您的属性名称代替 Full_Name)

   SELECT 
   LEFT(Full_Name,CHARINDEX(' ',Full_Name + ' ')-1)  AS FIRST_Name,
   Rtrim(substring(Full_Name,CHARINDEX(' ',Full_Name,0)+1,len(Full_Name)-CHARINDEX(' ',Full_Name,0)+1-CHARINDEX(' ', REVERSE(Full_Name)))) Middle_Name,
   Right(Full_Name,ISNULL(NULLIF(CHARINDEX(' ', REVERSE(Full_Name)) - 1,-1), LEN(Full_Name))) AS Last_Name
   FROM [Test].[dbo].[TEST]

【讨论】:

【参考方案10】:

我不了解 SQL 服务器,但在 mysql 中,我这样做是为了获取名字和中间名:

SELECT DISTINCT substring_index(name_column, ' ', 1) as First_name,
substring_index((substring_index(name_column, ' ', -2))," ",1) as Middle_name from table;

【讨论】:

当您不确定它是否适用于作者系统时,请不要猜测 :)

以上是关于从 SQL Server 中的名称字符串中获取中间名和名字的主要内容,如果未能解决你的问题,请参考以下文章

如何从 SQL Server 中的日期获取月份编号(不是月份名称)?

从数字获取 SQL Server 中的日期名称时出现问题

如何从 SQL Server 中的日期返回月份短格式?

几个SQL Server的查询题!

从 SQL Server 中的字符串中删除所有空格

在 SQL Server 中获取特定年份中的列作为月份名称