我有一个表,它的用户名是这样的。
Name
-----
Smith-Bay, Michael R.
Abbott, David Jr.
Actor, Cody
Agular, Stephen V.
我需要这个名字看起来像:
Last First MI
-------------------------
Smith-Bay Michael R
Abbott David Jr
Actor Cody
Agular Stephen V
我有以下SQL将名称拆分为第一个和最后一个:
select vl.lastname, vf.firstname
from users as t cross apply
(values (left(t.name, charindex(', ', t.name)), stuff(t.name, 1,
charindex(', ', t.name) + 1, ''))) vl(lastname, rest)
cross apply
(values (left(vl.rest, charindex(' ', vl.rest + ' ')))) vf(firstname)
order by vl.lastname
我如何应用另一个十字架申请来提取名字后的数字减去末尾的句点?
答案 0 :(得分:1)
在定期处理ETL时,我不得不在很多情况下执行此操作,或者由于数据存储不良而需要从字符串中提取项目,或者只是必须从报表中提取数据。数据并不总是很好地打包在单独的列中,我发现自己出于各种原因而解析数据。希望您正在解析的数据是一致的。不一致的数据会使这变得更加困难或不可能。如果您可以依靠自己的名字来正确地使用格式,那么您建议我的下面的方法可以完美地工作。我已经在很多场合使用过。
下面的方法我已经使用了许多不同的语言。我已经在MS ACCESS,Microsoft SSMS和C#中完成了此操作。我的示例来自Oracle。
基本思想是:
Find the character positions
,用于分隔您的名字,姓氏和中间名初始字符串。
Extract Strings into New Columns
使用获得的字符位置。
代码如下:
WITH character_pos AS
(
/* First we need the character positions for spaces, commas and the period for the middle initial */
SELECT name
/* Find 1st Space in the name so we can extract the first name from the string */
, instr(name, ', ') AS comma_1st_space_pos
/* Find 2nd Space in the name so we can extract the last name from the string */
, instr(name, ' ', 1, 2) AS comma_2nd_space_pos
/* Get the Length of the last name so we know how many characters the substr function should extract */
, instr(name, ' ', 1, 2) - (instr(name, ', ') + 2) AS last_name_length
/* Find period in the name so we can extract the Middle Initial should it exist */
, instr(name, '.') AS period_pos
, (instr(name, '.') - 1) - instr(name, ' ', 1, 2) AS middle_initial_length
FROM parse_name
) /* END character_pos CTE */
SELECT name
, substr(name, 0, comma_1st_space_pos -1) AS last_name
, CASE WHEN period_pos = 0 THEN substr(name, comma_1st_space_pos + 2)
ELSE substr(name, comma_1st_space_pos + 2, last_name_length)
END AS first_name
, substr(name, comma_2nd_space_pos + 1, middle_initial_length) AS middle_initial
, comma_1st_space_pos, comma_2nd_space_pos, last_name_length
, period_pos, middle_initial_length
FROM character_pos
;
我使用CTE只是在实际提取之外组织字符位置,但是所有这些都可以在一个SQL语句中完成。
基本上,这证明您只需要一些简单的字符串解析函数就不需要任何其他东西。您需要的只是Instring和Substring,它们通常可用任何语言提供。不需要存储过程,不需要临时表,也不需要额外的外部代码。除非原始问题的范围之外还有其他因素,否则有必要使用除SQL以外的其他任何东西。