sql - TSQL 替换规则:a|2$5.0| 为|5.0|5.0|
问题描述
我有一个带有字符串字段的表,例如 a|2$5.0| 我需要将其转换为以下a|5.0|5.0|。
我正在使用 SQL Server 2016。
逻辑如下:
- a - 是每个字符串的第一个字符
- | - 是列表元素分隔符
- $ - 如果字符串中有 $ 符号,则元素($ 和 | 符号之间的值)应重复与 $ 符号前面的数字的值一样多的次数(在我的示例中为 2 次)。
字符串也可以更复杂,但同样的逻辑适用,例如:
a|2$5.0|3.1|-4.2|3$-9.6|
应转换为:
a|5.0|5.0|3.1|-4.2|-9.6|-9.6|-9.6|
任何帮助将不胜感激。提前致谢。
解决方案
老实说,就像评论说的那样,我建议修复设计。老实说,在数据库中存储分隔数据是个坏主意。T-SQL 在这里也是一个糟糕的选择,因为它远不擅长字符串操作。
话虽如此,你可以做到这一点。我DelimitedSplit8K_LEAD
在这里使用,因为它是顺序位置感知的。如果您不在最新版本的 SQL Server 上,STRING_AGG
则需要用旧FOR XML PATH
方法替换:
SELECT STRING_AGG(NS.NewString,'|') WITHIN GROUP (ORDER BY DS.ItemNumber,T.I) + '|' AS NewString
FROM (VALUES('a|2$5.0|3.1|-4.2|3$-9.6|'))V(YourString)
CROSS APPLY dbo.DelimitedSplit8K_LEAD(V.YourString,'|') DS
CROSS APPLY (VALUES(CHARINDEX('$',DS.Item)))CI(I)
CROSS APPLY (VALUES(ISNULL(LEFT(DS.Item,NULLIF(CI.I,0)-1),1)))R(I)
CROSS APPLY (VALUES(STUFF(DS.Item,1,CI.I,'')))NS(NewString)
JOIN (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10))T(I) ON R.I >= T.I;
推荐阅读
- c - 中断组合键(例如 CTRL-C)如何以及何时转换为信号?
- swift - Swift 4 - 使用 evaluateJavaScript 为 webKit 设置值
- javascript - 回调函数的自定义参数取决于事件
- reactjs - Redux reducer - modifying array with forEach
- angularjs - 是否有 angularjs 形式的属性来仅获取更改的值?
- c# - EF Core MySQL - LINQ 语句创建低效查询
- web-scraping - 使用 html 标签从谷歌搜索页面抓取网页
- html - 1024px 容器内的 100vw 图像导致小水平滚动
- javascript - 如果有二维坐标,如何获取一维数组的信息?
- node.js - socket.io 和异步查询有问题