Sql-Server
在分隔符之間提取/解析資訊
我有一列,其中有 10 個由管道字元分隔的“欄位”,如下所示:
特克斯 | 更多文字 | 某事這裡 | 更多資訊 | 更多這裡 | 等| 等|
我一直在嘗試提取管道之間的內容,我可以做前兩個,但在那之後,我的大腦陷入了一個初始循環,我無法繞開它。
例如。表名是 MyTable,列是 MyColumn
SELECT TOP 10 MyTable.ItemsID, MyTable.MyColumn (SELECT SUBSTRING (MyTable.MyColumn,1,CHARINDEX('|', MyColumn)-1))as Pos1, (SELECT SUBSTRING(MyTable.MyColumn, CHARINDEX('|', MyColumn)+1,CHARINDEX('|', MyColumn))) as Pos2 FROM MyTable
我得到了位置 1 和 2 所需的東西,但是對於其餘的,我不知道該怎麼做。
我在想我需要獲取我的第三個管道的索引位置,但我的大腦凍結了,我嘗試了以下變化:
SELECT SUBSTRING(MyTable.MyColumn, CHARINDEX(SUBSTRING(MyTable.MyColumn, CHARINDEX('|', MyColumn)+1,CHARINDEX('|', MyColumn)))) as Pos3
我剛剛研究了 REPLACE 和 PARSENAME 函式。通過替換,我可以用點或句點替換管道字元,以便 PARSENAME 可以解析點分隔值。但是,我發現 PARSENAME 被限制為 4 個值。
我使用 STRING_SPLIT 得到了不錯的結果,但是,此功能需要兼容級別 130,我無法更改數據庫。我與它的互動是通過 API。
SELECT value FROM STRING_SPLIT ((select mytable.mycolumn from dbo.mytable), '|');
我通常使用這個腳本:
create table #temp (id int, val varchar(50)) insert into #temp (id,val) values (1,'aaa|bbb|ccc|ddd'), (2,'aaa|bbb|ccc|ddd'), (3,'aaa|bbb|ccc|ddd'), (4,'aaa|bbb|ccc|ddd') select * from ( select * from #temp as t cross apply (select num=Row_Number() over (Order by (SELECT NULL)), value from string_split(t.val, '|') ) d) s pivot (max(value) for s.num in([1],[2],[3],[4])) a
您只需要再添加 6 個欄位。
此解決方案依賴於自 sql server 2016 以來可用的 STRING_SPLIT。
對此進行中繼以獲取替代方案:
您可以使用人們以前使用的字元串拆分功能
STRING_SPLIT
之一。如果你不想在你的數據庫中創建一個函式,或者只是想實現它
CHARINDEX
用於教育目的,看看這個:DECLARE @MyTable table ( ItemsID integer PRIMARY KEY, MyColumn varchar(100) NOT NULL ); INSERT @MyTable (ItemsID, MyColumn) VALUES (1, '1|2|3|4|5|6|7|8|9|0'), (2, 'AB|CD|EF|GH|IJ|KL|MN|OP|QR|ST'); SELECT MT.ItemsID, MT.MyColumn, Splits.Item1, Splits.Item2, Splits.Item3, Splits.Item4, Splits.Item5, Splits.Item6, Splits.Item7, Splits.Item8, Splits.Item9, Splits.Item10 FROM @MyTable AS MT CROSS APPLY ( SELECT Item1 = LEFT(MT.MyColumn, CA1.p1 - 1), Item2 = SUBSTRING(MT.MyColumn, CA1.p1 + 1, CA2.p2 - CA1.p1 - 1), Item3 = SUBSTRING(MT.MyColumn, CA2.p2 + 1, CA3.p3 - CA2.p2 - 1), Item4 = SUBSTRING(MT.MyColumn, CA3.p3 + 1, CA4.p4 - CA3.p3 - 1), Item5 = SUBSTRING(MT.MyColumn, CA4.p4 + 1, CA5.p5 - CA4.p4 - 1), Item6 = SUBSTRING(MT.MyColumn, CA5.p5 + 1, CA6.p6 - CA5.p5 - 1), Item7 = SUBSTRING(MT.MyColumn, CA6.p6 + 1, CA7.p7 - CA6.p6 - 1), Item8 = SUBSTRING(MT.MyColumn, CA7.p7 + 1, CA8.p8 - CA7.p7 - 1), Item9 = SUBSTRING(MT.MyColumn, CA8.p8 + 1, CA9.p9 - CA8.p8 - 1), Item10 = RIGHT(MT.MyColumn, LEN(MT.MyColumn) - CA9.p9) FROM (SELECT CHARINDEX('|', MT.MyColumn)) AS CA1 (p1) CROSS APPLY (SELECT CHARINDEX('|', MT.MyColumn, CA1.p1 + 1)) AS CA2 (p2) CROSS APPLY (SELECT CHARINDEX('|', MT.MyColumn, CA2.p2 + 1)) AS CA3 (p3) CROSS APPLY (SELECT CHARINDEX('|', MT.MyColumn, CA3.p3 + 1)) AS CA4 (p4) CROSS APPLY (SELECT CHARINDEX('|', MT.MyColumn, CA4.p4 + 1)) AS CA5 (p5) CROSS APPLY (SELECT CHARINDEX('|', MT.MyColumn, CA5.p5 + 1)) AS CA6 (p6) CROSS APPLY (SELECT CHARINDEX('|', MT.MyColumn, CA6.p6 + 1)) AS CA7 (p7) CROSS APPLY (SELECT CHARINDEX('|', MT.MyColumn, CA7.p7 + 1)) AS CA8 (p8) CROSS APPLY (SELECT CHARINDEX('|', MT.MyColumn, CA8.p8 + 1)) AS CA9 (p9) ) AS Splits;
輸出: