SQL Server Remove character between Pipe and semicolon

axkjgtzd  于 2023-02-28  发布在  其他
关注(0)|答案(2)|浏览(113)

I have an SQL Table with a column that stores keywords like this
keyword|44500903-8f09-40d8-a908-5fb3e03d145e;keyword2|441fb756-ff0a-473f-ad70-2f78d679e7d9

I need remove all characters between Pipe (including this) and semicolon, including this. The result must be:

Keyword; keyword2

Any ideas? I try to use, substring, trim etc... but didn't work.

2uluyalo

2uluyalo1#

Assuming you are on SQL Server 2022, then you can use STRING_SPLIT to split the values into rows on the semicolon ( ; ) with an ordinal position, then use LEFT and CHARINDEX to get the value up to the pipe ( | ), and finally reaggregate with STRING_AGG :

DECLARE @YourString varchar(500) = 'keyword|44500903-8f09-40d8-a908-5fb3e03d145e;keyword2|441fb756-ff0a-473f-ad70-2f78d679e7d9';

SELECT STRING_AGG(LEFT(SS.Value,CHARINDEX('|',SS.Value + '|')-1),'; ') WITHIN GROUP (ORDER BY SS.ordinal)
FROM STRING_SPLIT(@YourString,';',1) SS;

If you aren't on SQL Server 2022 you could use a different solution to split your values, such as a JSON splitter (2016+) or delimitedsplit8k_LEAD (2012+). If you aren't on SQL Server 2017+ you'll also need to switch out STRING_AGG for the "old" FOR XML PATH (and STUFF ) solution.

dfddblmv

dfddblmv2#

Here is a method that will work starting from SQL Server 2012 onwards.

We are tokenizing input string of tokens as XML. An intermediate result in t1(c) contains XML as follows:

<root>
  <r>keyword</r>
  <r>44500903-8f09-40d8-a908-5fb3e03d145e</r>
  <r>keyword2</r>
  <r>441fb756-ff0a-473f-ad70-2f78d679e7d9</r>
</root>

We just need to retrieve XML elements values in odd positions by using XPath predicate [position() mod 2 = 1] .

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (id INT IDENTITY PRIMARY KEY, tokens NVARCHAR(MAX));
INSERT @tbl (tokens) VALUES
(N'keyword|44500903-8f09-40d8-a908-5fb3e03d145e;keyword2|441fb756-ff0a-473f-ad70-2f78d679e7d9');
-- DDL and sample data population, end

DECLARE @separator CHAR(1) = ';'
    , @pipe CHAR(1) = '|';

SELECT t.*
    , REPLACE(c.query('data(/root/r[position() mod  2 = 1])')
        .value('text()[1]','NVARCHAR(MAX)'), SPACE(1), @separator) AS result
FROM @tbl AS t
CROSS APPLY (SELECT TRY_CAST('<root><r><![CDATA[' + 
    REPLACE(REPLACE(tokens,@pipe,@separator), @separator, ']]></r><r><![CDATA[') + 
    ']]></r></root>' AS XML)) AS t1(c);

Output

idresult
1keyword;keyword2

相关问题