首页 > 解决方案 > 替换 TSQL 中的符号特定位置

问题描述

每 3 个 | position 需要在输出下方添加符号。

样品:

input :'12Hr|AP,1.8|KR,10.8|KE,10.8|TN,2.9|'

**output :'12Hr|AP,1.8|KR,10.8|@KE,10.8|TN,2.9|'**

input : '12Hr|AP,1.8|KR,10.8|KE,10.8|TN,2.9|UP,3.40|KR,4.9|'

**output : '12Hr|AP,1.8|KR,10.8|@KE,10.8|TN,2.9|UP,3.40|@KR,4.9|SS,4.9|AP,7.3|@'**

标签: sqlsql-servertsql

解决方案


假设:

  1. 术语“替换”使用不正确,因为您没有替换|预期输出中的管道 ( )
  2. 第二个输出是错误的,因为输入值在 终止KR,4.9,但在它之后还有 2 个附加值。

正如已经提到的,这不应该在 T-SQL 中完成,但这并不意味着它不能。一种方法是使用字符串拆分器,在管道上拆分它,然后重新聚合它,将@字符添加到正确的索引项中。

但是,您不能STRING_SPLIT为此使用内置的 SQL Server,因为它不尊重序数位置。因此我使用DelimitedSplit8K_LEAD; 这确实意味着我假设您的值的大小不能超过 8000 字节。

然后我使用 SQL Server 的内置STRING_AGG函数(如果您没有 2017+,则需要使用旧FOR XML PATH方法)重新聚合。在聚合中,我@在字符串的开头添加 a ,其中(itemnumber-1) % 3计算结果为0(每 3 个项目,偏移一个)并排除第一个项目(因为这将评估为0)。

SELECT STRING_AGG(CASE WHEN (DS.ItemNumber-1) % 3 = 0 AND DS.ItemNumber != 1 THEN '@' ELSE '' END + DS.Item,'|') WITHIN GROUP (ORDER BY DS.ItemNumber)
FROM (VALUES(1,'12Hr|AP,1.8|KR,10.8|KE,10.8|TN,2.9|'),
            (2,'12Hr|AP,1.8|KR,10.8|KE,10.8|TN,2.9|UP,3.40|KR,4.9|'))V(SomeID,YourString)
     CROSS APPLY dbo.DelimitedSplit8K_LEAD(V.YourString,'|') DS
GROUP BY V.SomeID;

推荐阅读