提取 SQL 服务器中某个位置或索引值之后的所有字符
Extract all the characters after a position or index value in SQL Server
以下是示例数据
100231|ABC Limited||Liquidated|514321||AU||Testwood|5165|5/14/1996 12:00:00 AM|8/1/2003 12:00:00 AM|Test1|Test2|
我想提取'|'的第12位之后的所有数据使用 SQL 服务器函数的管道定界符,即输出应为 |Test1|Test2|
我试过使用以下方法:
Select RIGHT(@InputValue,CHARINDEX('|',REVERSE(@InputValue))-1)
但它没有给出所需的输出。
不是最优雅的,但解决了给定的要求:
DECLARE @InputValue AS VARCHAR(200) = '100231|ABC Limited||Liquidated|514321||AU||Testwood|5165|5/14/1996 12:00:00 AM|8/1/2003 12:00:00 AM|Test1|Test2|'
SELECT
SUBSTRING(@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue) + 1
) + 1
) + 1
) + 1
) + 1
) + 1
) + 1
) + 1
) + 1
) + 1
) + 1
)
,LEN(@InputValue))
假设你知道总会有 14 个'|'每个字符串你可以使用更缩写的版本,例如:
DECLARE @InputValue AS VARCHAR(200) = '100231|ABC Limited||Liquidated|514321||AU||Testwood|5165|5/14/1996 12:00:00 AM|8/1/2003 12:00:00 AM|Test1|Test2|'
SELECT
RIGHT(@InputValue,
CHARINDEX('|',REVERSE(@InputValue),
CHARINDEX('|',REVERSE(@InputValue),
CHARINDEX('|',REVERSE(@InputValue)) + 1
) + 1
)
)
您也可以为此使用递归 CTE。
让它计算分隔符的位置。
然后 select 基于计算位置的子字符串。
WITH CTE AS
(
SELECT
1 as FieldNr,
-- LEFT(@InputValue,CHARINDEX('|', @InputValue)-1) AS Field,
0 as Pos1,
CHARINDEX('|',@InputValue) as Pos2
UNION ALL
SELECT
FieldNr+1,
-- SUBSTRING(@InputValue, Pos2+1, CHARINDEX('|',@InputValue, Pos2+1)-Pos2-1),
Pos2,
CHARINDEX('|',@InputValue, Pos2+1)
FROM CTE
WHERE Pos2 > 0 AND Pos2 < LEN(@InputValue)
)
SELECT SUBSTRING(@InputValue, MIN(Pos1)+1, MAX(Pos2)-MIN(Pos1)) AS AfterFieldNr
FROM CTE
WHERE FieldNr > 12;
Returns:
Test1|Test2|
在 rextester 上测试 here。
但如果您有 SQL Server 2017 或更高版本,则可以使用 STRING_SPLIT
和 STRING_AGG
。
SELECT STRING_AGG(value,'|') AS After12
FROM
(
SELECT
value,
ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS rn
FROM STRING_SPLIT(@InputValue, '|')
) AS q
WHERE rn > 12;
db<>fiddle here
以下是示例数据
100231|ABC Limited||Liquidated|514321||AU||Testwood|5165|5/14/1996 12:00:00 AM|8/1/2003 12:00:00 AM|Test1|Test2|
我想提取'|'的第12位之后的所有数据使用 SQL 服务器函数的管道定界符,即输出应为 |Test1|Test2|
我试过使用以下方法:
Select RIGHT(@InputValue,CHARINDEX('|',REVERSE(@InputValue))-1)
但它没有给出所需的输出。
不是最优雅的,但解决了给定的要求:
DECLARE @InputValue AS VARCHAR(200) = '100231|ABC Limited||Liquidated|514321||AU||Testwood|5165|5/14/1996 12:00:00 AM|8/1/2003 12:00:00 AM|Test1|Test2|'
SELECT
SUBSTRING(@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue,
CHARINDEX('|',@InputValue) + 1
) + 1
) + 1
) + 1
) + 1
) + 1
) + 1
) + 1
) + 1
) + 1
) + 1
)
,LEN(@InputValue))
假设你知道总会有 14 个'|'每个字符串你可以使用更缩写的版本,例如:
DECLARE @InputValue AS VARCHAR(200) = '100231|ABC Limited||Liquidated|514321||AU||Testwood|5165|5/14/1996 12:00:00 AM|8/1/2003 12:00:00 AM|Test1|Test2|'
SELECT
RIGHT(@InputValue,
CHARINDEX('|',REVERSE(@InputValue),
CHARINDEX('|',REVERSE(@InputValue),
CHARINDEX('|',REVERSE(@InputValue)) + 1
) + 1
)
)
您也可以为此使用递归 CTE。
让它计算分隔符的位置。
然后 select 基于计算位置的子字符串。
WITH CTE AS
(
SELECT
1 as FieldNr,
-- LEFT(@InputValue,CHARINDEX('|', @InputValue)-1) AS Field,
0 as Pos1,
CHARINDEX('|',@InputValue) as Pos2
UNION ALL
SELECT
FieldNr+1,
-- SUBSTRING(@InputValue, Pos2+1, CHARINDEX('|',@InputValue, Pos2+1)-Pos2-1),
Pos2,
CHARINDEX('|',@InputValue, Pos2+1)
FROM CTE
WHERE Pos2 > 0 AND Pos2 < LEN(@InputValue)
)
SELECT SUBSTRING(@InputValue, MIN(Pos1)+1, MAX(Pos2)-MIN(Pos1)) AS AfterFieldNr
FROM CTE
WHERE FieldNr > 12;
Returns:
Test1|Test2|
在 rextester 上测试 here。
但如果您有 SQL Server 2017 或更高版本,则可以使用 STRING_SPLIT
和 STRING_AGG
。
SELECT STRING_AGG(value,'|') AS After12
FROM
(
SELECT
value,
ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS rn
FROM STRING_SPLIT(@InputValue, '|')
) AS q
WHERE rn > 12;
db<>fiddle here