在SELECT语句中将名称拆分为多个部分

时间:2018-08-21 19:50:16

标签: sql sql-server tsql

我似乎找不到有关将字符串拆分为所需部分的现有文章。我在SQL Server中有一个数据库字段,其中包含“姓氏名MI”(没有逗号,只是用空格分隔人名的每个部分)。我有以下SQL来获取名字和姓氏,但无法弄清楚如何获得中间名的首字母或中间名。

例如Doe John B

SELECT
    RTRIM(LEFT([PATIENT_NAME], CHARINDEX(' ', [PATIENT_NAME]))) AS LastName,
    SUBSTRING([PATIENT_NAME], CHARINDEX(' ', [PATIENT_NAME]) + 1, LEN([PATIENT_NAME])) AS FirstName
FROM
    Clients

结果:

  • 名字= John B
  • 姓氏=母鹿

如何仅返回没有中间名首字母的名字,并在此SELECT语句中从该字符串中获取'B'作为中间名?

4 个答案:

答案 0 :(得分:2)

您可以采用正确的1个字符,也可以采用第一个字符反转字符串。

SELECT RIGHT(LTRIM(RTRIM([Patient_Name])), 1) AS Middle_Initial

SELECT LEFT(REVERSE(LTRIM(RTRIM([Patient_Name]))), 1) AS Middle_Initial

关于从您的名字字符串中删除MI,我要么找到字符串的长度并取左N-2个字符,要么我对空间进行charindex然后取那么多字符。放在一起:

DECLARE @name VARCHAR(100) = 'Smith David M      ' 

--Clean the string of leading/trailing whitespace
SELECT LTRIM(RTRIM(@name)) AS name_cleaned

--Find the first space to parse out the last name
SELECT CHARINDEX(' ', @name) AS first_space

--Select all chars before the first space
SELECT LEFT(LTRIM(RTRIM(@name)), CHARINDEX(' ', @name)-1) AS last_name

--Find the next space, use the starting location as the previous space and add 1
SELECT CHARINDEX(' ', @name, 7) AS second_space

--Select all chars between the spaces
SELECT SUBSTRING(@name, CHARINDEX(' ', @name)+1, CHARINDEX(' ', @name, 7) - CHARINDEX(' ', @name)) AS first_name

--Select the right most char for middle initial
SELECT RIGHT(LTRIM(RTRIM(@name)), 1) AS middle

答案 1 :(得分:1)

您可以使用句点字符(。)替换空格字符,并使用PARSENAME()。

请注意,这将适用于名称的所有3个部分,而不仅仅是中间的首字母。

答案 2 :(得分:1)

在姓氏上使用CHARINDEX时,将其用作子字符串的长度。然后,在FirstName上,再次使用它作为子字符串的开始位置。现在,在CHARINDEX上的中间花样,您必须包括起始位置,即LEN减去姓氏CHARINDEX。这将为您提供第二个空格,即您要开始使用中间名的位置。

请参见下面的示例:

DECLARE @tb TABLE (PATIENT_NAME varchar(250));
INSERT INTO @tb VALUES 
('Doe John B')

DECLARE 
    @LastName       INT
,   @Middle         INT 

SELECT 
    @LastName       =  CHARINDEX(' ', PATIENT_NAME)
,   @Middle         =  CHARINDEX(' ', PATIENT_NAME,  LEN(PATIENT_NAME) - CHARINDEX(' ', PATIENT_NAME))
FROM @tb


SELECT 
    SUBSTRING(PATIENT_NAME, 1, @LastName) LastName
,   SUBSTRING(PATIENT_NAME, @LastName, LEN(PATIENT_NAME) - @LastName) FirstName 
,   SUBSTRING(PATIENT_NAME, @Middle, LEN(PATIENT_NAME) - @Middle + 1 ) Middle  
FROM @tb   

我已经声明了一些变量来使事情更具可读性,但是您可以在没有它们的情况下进行操作。

当然,LEFTRIGHT是采用姓氏和中间名的更简单方法。除了使用诸如REVERSETRIM之类的辅助功能外,我更喜欢PARSENAME作为一种更简单,更简洁的方法。
这是一个示例:

SELECT 
    PARSENAME(REPLACE(PATIENT_NAME,' ','.'),3) LastName
,   PARSENAME(REPLACE(PATIENT_NAME,' ','.'),2) FirstName
,   PARSENAME(REPLACE(PATIENT_NAME,' ','.'),1) Middle

答案 3 :(得分:0)

由于必须从字符串中提取的元素数量是固定的(3),因此可以使用基于XML的拆分:

APP_KEY

结果:

enter image description here

如您所见,它甚至可以使用随机间隔的名称。