我正在嘗試替換包含這兩個字符的倍數的字串中兩個特定字符之間的任何內容。將其作為 csv 格式。
這是我在該欄位中獲得的資料示例:
0001, ABCD1234;0002, EFGH432562;0003, IJKL1345hsth;...
我需要從中檢索的是“,”之前的所有部分,而不是“,”和“;”之間的所有部分
我嘗試了這些公式但沒有成功
SELECT REPLACE(fieldname, ',[A-Z];', ' ') FROM ...
or
SELECT REPLACE(fieldname, ',*;', ' ') FROM ...
我需要得到
0001 0002 0003
有沒有辦法做到這一點?
uj5u.com熱心網友回復:
您可以CROSS APPLY到STRING_SPLIT使用STRING_AGG (由于SQL服務器2017年)堅持數字重新走到一起。
select id, codes from your_table cross apply ( select string_agg(left(value, patindex('%_,%', value)), ' ') as codes from string_split(fieldname, ';') s where value like '%_,%' ) ca; GO
| ID | 代碼 |
|---|---|
| 1 | 0001 0002 0003 |
關于db<>fiddle 的演示在這里
uj5u.com熱心網友回復:
如果您使用的是 SQL Server 2017并且不需要保證訂單將得到維護,那么LukStorms 的答案就完全足夠了。
但是,如果您:
- 關心訂單保證;或者,
- 版本早于 2017 年(并且不能使用
STRING_AGG);或者, - 比 2016 年版本更舊或兼容級別更低(并且不能使用
STRING_SPLIT):
這是一個可以提供幫助的有序拆分函式(它又長又丑,但您只需創建一次):
CREATE FUNCTION dbo.SplitOrdered
(
@list nvarchar(max),
@delim nvarchar(10)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
WITH w(n) AS (SELECT 0 FROM (VALUES (0),(0),(0),(0)) w(n)),
k(n) AS (SELECT 0 FROM w a, w b),
r(n) AS (SELECT 0 FROM k a, k b, k c, k d, k e, k f, k g, k h),
p(n) AS (SELECT TOP (COALESCE(LEN(@list), 0))
ROW_NUMBER() OVER (ORDER BY @@SPID) -1 FROM r),
spots(p) AS
(
SELECT n FROM p
WHERE (SUBSTRING(@list, n, LEN(@delim 'x') - 1) LIKE @delim OR n = 0)
),
parts(p,val) AS
(
SELECT p, SUBSTRING(@list, p LEN(@delim 'x') - 1,
LEAD(p, 1, 2147483647) OVER (ORDER BY p) - p - LEN(@delim))
FROM spots AS s
)
SELECT listpos = ROW_NUMBER() OVER (ORDER BY p),
Item = LTRIM(RTRIM(val))
FROM parts
);
那么查詢可以變成:
;WITH x AS
(
SELECT id, listpos,
codes = LEFT(Item, COALESCE(NULLIF(CHARINDEX(',', Item),0),1)-1)
FROM dbo.your_table
CROSS APPLY dbo.SplitOrdered(fieldname, ';') AS c
)
SELECT id, codes = (
(SELECT x2.codes ' '
FROM x AS x2
WHERE x2.id = x.id
ORDER BY x2.listpos
FOR XML PATH(''), TYPE).value(N'./text()[1]', N'nvarchar(max)')
)
FROM x GROUP BY id;
- 從 LukStorms 的 db<>fiddle 借用的示例
請注意,除了保證順序和向后兼容(嗯,只支持這么多版本),它還忽略垃圾資料,例如嘗試:
0001, ABCD1234;0002 but no comma
uj5u.com熱心網友回復:
我將首先使用拆分器函式并找到 char ',' 位置來對其進行子串化。
我的分離器功能:
CREATE FUNCTION [dbo].[Split_Comma_Delimited] (
@InputString VARCHAR(8000),
@Delimiter VARCHAR(50)
)
RETURNS @Items TABLE (
Item VARCHAR(8000)
)
AS
BEGIN
IF @Delimiter = ' '
BEGIN
SET @Delimiter = ','
SET @InputString = REPLACE(@InputString, ' ', @Delimiter)
END
IF (@Delimiter IS NULL OR @Delimiter = '')
SET @Delimiter = ','
--INSERT INTO @Items VALUES (@Delimiter) -- Diagnostic
--INSERT INTO @Items VALUES (@InputString) -- Diagnostic
DECLARE @Item VARCHAR(8000)
DECLARE @ItemList VARCHAR(8000)
DECLARE @DelimIndex INT
SET @ItemList = @InputString
SET @DelimIndex = CHARINDEX(@Delimiter, @ItemList, 0)
WHILE (@DelimIndex != 0)
BEGIN
SET @Item = SUBSTRING(@ItemList, 0, @DelimIndex)
INSERT INTO @Items VALUES (@Item)
-- Set @ItemList = @ItemList minus one less item
SET @ItemList = SUBSTRING(@ItemList, @DelimIndex 1, LEN(@ItemList)-@DelimIndex)
SET @DelimIndex = CHARINDEX(@Delimiter, @ItemList, 0)
END -- End WHILE
IF @Item IS NOT NULL -- At least one delimiter was encountered in @InputString
BEGIN
SET @Item = @ItemList
INSERT INTO @Items VALUES (@Item)
END
-- No delimiters were encountered in @InputString, so just return @InputString
ELSE INSERT INTO @Items VALUES (@InputString)
RETURN
END -- End Function
GO
之后使用這個:
select * , CHARINDEX(',', Item) , SUBSTRING(Item,0,CHARINDEX(',', Item)) column_you_want FROM
[dbo].[Split_Comma_Delimited] ('0001, ABCD1234;0002, EFGH432562;0003, IJKL1345hsth;' , ';')
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/408473.html
標籤:
