查询中包含多个 CHARINDEX 选项的 SUBSTRING
SUBSTRING with multiple CHARINDEX options in query
我试图仅从中提取姓氏的列具有可能的组合,如 H.Naude
或 H. Naude
或 H Naude
,我只需要 Naude
部分.如果我使用 SUBSTRING
方法,我可以在 space 或点之后获取字符,但是如何测试所有 3 种可能性?不幸的是,此数据来自导入的条目表单,因此我无法控制数据的格式。目前我有以下内容仅适用于 space 字符
SUBSTRING(H.PtsNonFemale, CHARINDEX('' '', H.PtsNonFemale) +1, DATALENGTH(H.PtsNonFemale) - CHARINDEX('' '', H.PtsNonFemale) +1 ) AS Female
非常感谢任何帮助。
假设提供的数据涵盖所有 use-cases 那么您可以简单地按照要删除的组件的长度降序测试每种情况,并使用在子字符串中找到的第一个匹配项(最长)。
SELECT H.PtsNonFemale
, SUBSTRING(H.PtsNonFemale, COALESCE(NULLIF(I.A,0)+6,NULLIF(I.B,0)+2,NULLIF(I.C,0)+1,NULLIF(I.D,0)+1), LEN(H.PtsNonFemale)) AS Female
FROM (
VALUES
('H.Naude'), ('H. Naude'), ('H Naude'), ('A. M. Someone')
) H (PtsNonFemale)
CROSS APPLY (
VALUES
(PATINDEX('_. _. %', H.PtsNonFemale), CHARINDEX('. ',H.PtsNonFemale,0), CHARINDEX('.',H.PtsNonFemale,0), CHARINDEX(' ',H.PtsNonFemale,0))
) I (A, B, C, D);
Returns:
PtsNonFemale
Female
H.Naude
Naude
H. Naude
Naude
H Naude
Naude
A. M. Someone
Someone
将一串标记标记化而不是解析要好得多。
SQL Server XQuery 可以很容易地做到这一点。
无需多次调用字符串函数SUBSTRING(), COALESCE(), NULLIF(), LEN(), PATINDEX(), CHARINDEX()
等弹幕
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, PtsNonFemale VARCHAR(100));
INSERT INTO @tbl (PtsNonFemale) VALUES
('H.Naude'),
('H. Naude'),
('H Naude'),
('A. M. Someone');
-- DDL and sample data population, end
DECLARE @separator CHAR(1) = '.';
SELECT t.*
, c.value('(/root/r[last()]/text())[1]', 'VARCHAR(30)') AS Female
FROM @tbl AS t
CROSS APPLY (SELECT TRY_CAST('<root><r><![CDATA[' +
REPLACE(REPLACE(PtsNonFemale,SPACE(1),@separator), @separator, ']]></r><r><![CDATA[') +
']]></r></root>' AS XML)) AS t1(c);
输出
+----+---------------+---------+
| ID | PtsNonFemale | Female |
+----+---------------+---------+
| 1 | H.Naude | Naude |
| 2 | H. Naude | Naude |
| 3 | H Naude | Naude |
| 4 | A. M. Someone | Someone |
+----+---------------+---------+
使用string_split()
:
select
PtsNonFemale,
(select top 1 value
from string_split(PtsNonFemale, ' ', 1)
order by ordinal desc) as Female
from mytable
我试图仅从中提取姓氏的列具有可能的组合,如 H.Naude
或 H. Naude
或 H Naude
,我只需要 Naude
部分.如果我使用 SUBSTRING
方法,我可以在 space 或点之后获取字符,但是如何测试所有 3 种可能性?不幸的是,此数据来自导入的条目表单,因此我无法控制数据的格式。目前我有以下内容仅适用于 space 字符
SUBSTRING(H.PtsNonFemale, CHARINDEX('' '', H.PtsNonFemale) +1, DATALENGTH(H.PtsNonFemale) - CHARINDEX('' '', H.PtsNonFemale) +1 ) AS Female
非常感谢任何帮助。
假设提供的数据涵盖所有 use-cases 那么您可以简单地按照要删除的组件的长度降序测试每种情况,并使用在子字符串中找到的第一个匹配项(最长)。
SELECT H.PtsNonFemale
, SUBSTRING(H.PtsNonFemale, COALESCE(NULLIF(I.A,0)+6,NULLIF(I.B,0)+2,NULLIF(I.C,0)+1,NULLIF(I.D,0)+1), LEN(H.PtsNonFemale)) AS Female
FROM (
VALUES
('H.Naude'), ('H. Naude'), ('H Naude'), ('A. M. Someone')
) H (PtsNonFemale)
CROSS APPLY (
VALUES
(PATINDEX('_. _. %', H.PtsNonFemale), CHARINDEX('. ',H.PtsNonFemale,0), CHARINDEX('.',H.PtsNonFemale,0), CHARINDEX(' ',H.PtsNonFemale,0))
) I (A, B, C, D);
Returns:
PtsNonFemale | Female |
---|---|
H.Naude | Naude |
H. Naude | Naude |
H Naude | Naude |
A. M. Someone | Someone |
将一串标记标记化而不是解析要好得多。
SQL Server XQuery 可以很容易地做到这一点。
无需多次调用字符串函数SUBSTRING(), COALESCE(), NULLIF(), LEN(), PATINDEX(), CHARINDEX()
等弹幕
SQL
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, PtsNonFemale VARCHAR(100));
INSERT INTO @tbl (PtsNonFemale) VALUES
('H.Naude'),
('H. Naude'),
('H Naude'),
('A. M. Someone');
-- DDL and sample data population, end
DECLARE @separator CHAR(1) = '.';
SELECT t.*
, c.value('(/root/r[last()]/text())[1]', 'VARCHAR(30)') AS Female
FROM @tbl AS t
CROSS APPLY (SELECT TRY_CAST('<root><r><![CDATA[' +
REPLACE(REPLACE(PtsNonFemale,SPACE(1),@separator), @separator, ']]></r><r><![CDATA[') +
']]></r></root>' AS XML)) AS t1(c);
输出
+----+---------------+---------+
| ID | PtsNonFemale | Female |
+----+---------------+---------+
| 1 | H.Naude | Naude |
| 2 | H. Naude | Naude |
| 3 | H Naude | Naude |
| 4 | A. M. Someone | Someone |
+----+---------------+---------+
使用string_split()
:
select
PtsNonFemale,
(select top 1 value
from string_split(PtsNonFemale, ' ', 1)
order by ordinal desc) as Female
from mytable