[英]Extracting multiple values from string and ordering them
我在 Notes 字段中有一些值,這些值由如下值組成,其中 abc 代表不同的詞:
請求說明:VAR - abc abc abc abc abc
不幸的是,數據存儲方式的設計非常糟糕,我需要為每個“Required Notes:”記錄提取注釋類型。 它還需要從最近到最舊的順序(字符串的最后一部分到字符串的第一部分)。
CREATE TABLE #TestData
(
ClientID int,
Notes varchar(8000)
)
insert into #TestData
(
ClientID,
Notes
)
select
1,
'Request Notes: VAR - abc abc abc abc abc'
union all
select
2,
'Request Notes: OZR - abc abc abc abc abc Request Notes: ACC - abc abc abc abc abc Request Notes: TYU - abc abc abc abc abc'
union all
select
3,
'Request Notes: TYU - abc abc abc abc abc Request Notes: VAR - abc abc abc abc abc'
這就是我期望上述示例的輸出方式:
--Expected Output
Client ID Type Order
1 VAR 1
2 TYU 1
2 ACC 2
2 OZR 3
3 VAR 1
3 TYU 2
到目前為止,我把它放在一起提取了 OZR,但我對如何獲取其他列表並將列表排序到上面的預期輸出中感到困惑。
DECLARE @Text varchar(500) = 'Request Notes: OZR - abc abc abc abc abc Request Notes: ACC - abc abc abc abc abc Request Notes: TYU - abc abc abc abc abc'
SELECT TRIM(REPLACE(REPLACE(SUBSTRING(@Text, CHARINDEX(':', @Text), CHARINDEX('-',@text) - CHARINDEX(':', @Text) + Len('-')),':',''),'-',''))
您可以使用openjson將數據提取為數組並進行過濾:
select d.ClientId, n.*
from #testdata d
cross apply (
select
Left(j.[value],3) [Type],
Row_Number() over(order by Convert(int,j.[key]) desc) [Order]
from OpenJson(Concat('["',replace(notes,'Notes: ', '","'),'"]')) j
where j.[value] != 'Request'
)n;
示例小提琴
這是遞歸 CTE 版本。 它根據查找“Request Notes:”拆分字符串,然后進行左/右組合以提取 3 個字母的代碼。 它在構建時迭代順序。 然后您從 CTE 中選擇並只獲取有一些 NotesRemainder 的行:
;
WITH CTESplit
AS (
SELECT ClientID,
RIGHT(LEFT(Notes, CHARINDEX('Request Notes:', Notes) + 17), 3) AS NotesPart,
RIGHT(Notes, LEN(Notes) - CHARINDEX('Request Notes:', Notes) - 17) AS NotesRemainder,
-1 AS [Order]
FROM #TestData
WHERE Notes IS NOT NULL AND CHARINDEX('Request Notes:', Notes) > 0
UNION ALL
SELECT CTESplit.ClientID,
RIGHT(LEFT(CTESplit.NotesRemainder, CHARINDEX('Request Notes:', CTESplit.NotesRemainder) + 17), 3),
RIGHT(CTESplit.NotesRemainder, LEN(CTESplit.NotesRemainder) - CHARINDEX('Request Notes:', CTESplit.NotesRemainder)),
CTESplit.[Order] - 1
FROM CTESplit
WHERE CTESplit.NotesRemainder IS NOT NULL AND CHARINDEX('Request Notes:', CTESplit.NotesRemainder) > 0
UNION ALL
SELECT CTESplit.ClientID,
RIGHT(LEFT(CTESplit.NotesRemainder, CHARINDEX('Request Notes:', CTESplit.NotesRemainder) + 17), 3),
NULL,
CTESplit.[Order] - 1
FROM CTESplit
WHERE CTESplit.NotesRemainder IS NOT NULL AND CHARINDEX('Request Notes:', CTESplit.NotesRemainder) = 0
)
SELECT CS.ClientID,
CS.NotesPart AS Type,
CS.[Order] +(SELECT MIN([Order])*-1 FROM CTESplit WHERE ClientID = CS.ClientID) AS [Order]
FROM CTESplit AS CS
WHERE CS.NotesRemainder IS NOT NULL
ORDER BY CS.ClientID,
CS.[Order] ASC;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.