[英]Extracting a string in between two characters in sql
I am having trouble extracting a selection of characters from a string 我在从字符串中提取字符选择时遇到麻烦
Here is a snippet of values from a field called 'TXT': 以下是来自“ TXT”字段的值的摘要:
And I wish to extract the F333330, F010122, F10101 and F27272 我希望提取F333330,F010122,F10101和F27272
I have experimented with charindex, left/right, and substring but havent been able to crack it 我已经尝试过charindex,left / right和substring,但是还无法破解
SELECT TXT ,
CASE WHEN CHARINDEX('-',(SUBSTRING(txt,CHARINDEX('-',txt,2)+1,99)))=0
THEN
LTRIM(RTRIM(SUBSTRING(txt,CHARINDEX('-',txt,2)+1,99)))
ELSE
LTRIM(RTRIM(SUBSTRING(txt,CHARINDEX('-',txt,2) +1,CHARINDEX('-',SUBSTRING(txt,CHARINDEX('-',txt,2)+1,99))-1)))
END
FROM #test
My desired row set is to just show: 我想要的行集只是显示:
I have tried other variations of substring without a case statement but had no luck. 我尝试了没有用case语句的子字符串的其他变体,但是没有运气。 Can anyone help?
有人可以帮忙吗?
Thanks, Nuems 谢谢,努姆斯
Here is one option using parsename()
and a CROSS APPLY
这是使用
parsename()
和CROSS APPLY
一个选项
Example 例
Declare @YourTable table (Txt varchar(500))
Insert Into @YourTable values
('FNP, 10/09/2018,PO-00123456 - F333330- FA_002056')
,('FNP, 18-09-2018,PO-00987654 - F010122- FA_002056')
,('FNP, 28/12/2017,PO-00123987 - F10101')
,('FNP, 13-03-2019,FRPO-35412 - F27272-ANNUL PO')
Select A.Txt
,NewValue = case when parsename(S,3) is null then parsename(S,1) else parsename(S,2) end
From @YourTable A
Cross Apply (values ( replace(replace(parsename(replace(TXT,',','.'),1),'PO-','PO'),'-','.') )) B(S)
Returns 退货
Txt NewValue
FNP, 10/09/2018,PO-00123456 - F333330- FA_002056 F333330
FNP, 18-09-2018,PO-00987654 - F010122- FA_002056 F010122
FNP, 28/12/2017,PO-00123987 - F10101 F10101
FNP, 13-03-2019,FRPO-35412 - F27272-ANNUL PO F27272
Try this? 尝试这个?
DECLARE @test TABLE (TXT VARCHAR(500));
INSERT INTO @test SELECT 'FNP, 10/09/2018,PO-00123456 - F333330- FA_002056' UNION ALL
SELECT 'FNP, 18-09-2018,PO-00987654 - F010122- FA_002056' UNION ALL
SELECT 'FNP, 28/12/2017,PO-00123987 - F10101' UNION ALL
SELECT 'FNP, 13-03-2019,FRPO-35412 - F27272-ANNUL PO';
SELECT SUBSTRING(TXT, PATINDEX('%- F%', TXT) + 2, CASE WHEN CHARINDEX('-', SUBSTRING(TXT, PATINDEX('%- F%', TXT) + 2, 99)) = 0 THEN 99 ELSE CHARINDEX('-', SUBSTRING(TXT, PATINDEX('%- F%', TXT) + 2, 99)) - 1 END)
FROM @test;
...or, with that one extra row: ...或者,再增加一行:
DECLARE @test TABLE (TXT VARCHAR(500));
INSERT INTO @test SELECT 'FNP, 10/09/2018,PO-00123456 - F333330- FA_002056' UNION ALL
SELECT 'FNP, 18-09-2018,PO-00987654 - F010122- FA_002056' UNION ALL
SELECT 'FNP, 28/12/2017,PO-00123987 - F10101' UNION ALL
SELECT 'FNP, 13-03-2019,FRPO-35412 - F27272-ANNUL PO' UNION ALL
SELECT 'FNP, 11/10/2017,PO-00112311 - F32121 regul po 112311';
SELECT SUBSTRING(TXT, PATINDEX('%- F%', TXT) + 2,
CASE
WHEN CHARINDEX('-', SUBSTRING(TXT, PATINDEX('%- F%', TXT) + 2, 99)) != 0 THEN CHARINDEX('-', SUBSTRING(TXT, PATINDEX('%- F%', TXT) + 2, 99)) - 1
WHEN CHARINDEX(' ', SUBSTRING(TXT, PATINDEX('%- F%', TXT) + 2, 99)) != 0 THEN CHARINDEX(' ', SUBSTRING(TXT, PATINDEX('%- F%', TXT) + 2, 99)) - 1
ELSE 99
END)
FROM @test;
...or bonus with less repetition (uses a CTE): ...或重复次数较少的奖金(使用CTE):
WITH x AS (
SELECT SUBSTRING(TXT, PATINDEX('%- F%', TXT) + 2, 99) AS TXT FROM @test)
SELECT SUBSTRING(TXT, 0,
CASE
WHEN CHARINDEX('-', TXT) != 0 THEN CHARINDEX('-', TXT) - 1
WHEN CHARINDEX(' ', TXT) != 0 THEN CHARINDEX(' ', TXT) - 1
ELSE 99
END)
FROM x;
I know I'm a little late here but here's a fast an efficient way to do this assuming that the text begins with F and you know the min/max length of good values. 我知道我来晚了一点,但这是一种快速有效的方法,它假定文本以F开头并且您知道好的值的最小/最大长度。 For this example I'll assume that the value will be 5-7 characters long but this can be easily adjusted.
对于此示例,我假设该值的长度为5-7个字符,但是可以轻松调整。
DECLARE @YourTable table (SomeId INT IDENTITY PRIMARY KEY, Txt varchar(500))
Insert Into @YourTable values
('FNP, 10/09/2018,PO-00123456 - F333330- FA_002056')
,('FNP, 18-09-2018,PO-00987654 - F010122- FA_002056')
,('FNP, 28/12/2017,PO-00123987 - F10101')
,('FNP, 13-03-2019,FRPO-35412 - F27272-ANNUL PO')
SELECT
t.SomeID,
ItemLength = MAX(r.N),
ItemIndex = MAX(p.P),
Item = SUBSTRING(MAX(t.Txt),MAX(p.P),MAX(r.N)+1)
FROM @YourTable AS t
CROSS JOIN (VALUES(4),(5),(6)) AS r(N)
CROSS APPLY (VALUES('%F'+REPLICATE('[0-9A-Z]',r.N)+'%')) AS f(P)
CROSS APPLY (VALUES(PATINDEX(f.P,t.Txt))) AS p(P)
WHERE p.P > 0
GROUP BY t.SomeId
Returns: 返回值:
SomeID ItemLength ItemIndex Item
----------- ----------- ----------- ---------
1 6 31 F333330
2 6 31 F010122
3 5 31 F10101
4 5 30 F27272
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.