从 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_Name
、Middle_Name
和Last_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 中的名称字符串中获取中间名和名字的主要内容,如果未能解决你的问题,请参考以下文章