提问人:user3933327 提问时间:10/26/2023 最后编辑:Thom Auser3933327 更新时间:10/27/2023 访问量:118
获取第 3 次连字符 (-) 后的所有字符
Get all the characters after the 3rd hypen (-)
问:
我有列 TrackNo,其值如下
8070444981-010023-013123-INBBTC-C
601724-072923-078923-INAAAX-B
我需要从第三个连字符示例中获取值
-INBBTC-C
-INAAAX-B
我尝试了substring,charindex,但它不适用于这两种情况
select substring( Trackno,
charindex('-', TrackNo , (charindex('-', TrackNo , 1))
+charindex('-', TrackNo, (charindex('-', TrackNo , 1))+1)),20)
from table
答:
-2赞
Yitzhak Khabinsky
10/26/2023
#1
请尝试以下基于 XML 和 XQuery 的解决方案。
XPath 谓词正在为你的方案执行工作:The XPath predicate is doing the job for your scenario:/root/r[position() ge 4]
获取第 3 次连字符 (-) 后的所有字符
SQL算法
-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, Trackno VARCHAR(100));
INSERT INTO @tbl (Trackno) VALUES
('8070444981-010023-013123-INBBTC-C'),
('601724-072923-078923-INAAAX-B');
-- DDL and sample data population, end
DECLARE @separator CHAR(1) = '-';
SELECT t.*
, REPLACE(c.query('data(/root/r[position() ge 4])')
.value('text()[1]', 'VARCHAR(100)'), SPACE(1), @separator) AS result
FROM @tbl AS t
CROSS APPLY (SELECT TRY_CAST('<root><r><![CDATA[' +
REPLACE(Trackno, @separator, ']]></r><r><![CDATA[') +
']]></r></root>' AS XML)) AS t1(c);
输出
编号 | 轨道编号 | 结果 |
---|---|---|
1 | 8070444981-010023-013123-INBBTC-C | INBBTC-C型 |
2 | 601724-072923-078923-英纳AX-B | INAAAX-B型 |
评论
0赞
user3933327
10/27/2023
这给出了结果,但是你能分享我吗/是否有任何简短的解决方案,因为它用于 SP 的 select 语句中,其中包含具有多个连接的大量数据
0赞
Yitzhak Khabinsky
10/27/2023
建议的解决方案将在 SP 中起作用:(1) 在实际表下添加联接,(2) 添加到子句中。CROSS APPLY
Add REPLACE(...) as result
SELECT
1赞
Xedni
10/27/2023
#2
如果您有 SQL 2022,则可以使用可选的 ordinal 参数,并获取所需的任何部分(拆分后)。string_split
-
除此之外,您可以使用嵌套调用来暴力破解该部分,就像您所做的那样。你只需要确保你正确地偏移了每个块,这样你就不会在错误的地方切片。charindex
;with trackingNumbers (TrackNo) as
(
select '8070444981-010023-013123-INBBTC-C'
union all select '601724-072923-078923-INAAAX-B'
), b as
(
select
TrackNo,
FirstIndex = charindex('-', TrackNo),
SecondIndex = charindex
(
'-',
TrackNo,
charindex
(
'-',
TrackNo
) + 1
),
ThirdIndex = charindex
(
'-',
TrackNo,
charindex
(
'-',
TrackNo,
charindex
(
'-',
TrackNo
) + 1
) + 1
)
from trackingNumbers
)
select *,
LastTwo = substring(TrackNo, ThirdIndex + 1, 8000)
from b
如果需要,还可以通过替换字符串中的各种值来将其转换为JSON或XML数据的形式,还有其他方法可以做到这一点,但是为了解决您最初尝试的方法,我将避免使用这些方法。
编辑作为奖励,如果你想走这条路,这里有一些你可以通过连续交叉应用来做到这一点。
;with trackingNumbers (TrackNo) as
(
select '8070444981-010023-013123-INBBTC-C'
union all select '601724-072923-078923-INAAAX-B'
)
select
LastTwo = substring(TrackNo, d.ThirdIndex + 1, 8000),
FirstIndex,
SecondIndex,
ThirdIndex
from trackingNumbers a
cross apply
(
select FirstIndex = charindex('-', TrackNo)
) b
cross apply
(
select SecondIndex = charindex('-', TrackNo, b.FirstIndex + 1)
) c
cross apply
(
select ThirdIndex = charindex('-', TrackNo, c.SecondIndex + 1)
) d
评论
0赞
Stuck at 1337
10/27/2023
而不是只做 4000 或 8000 或其他什么。没有理由让其中一个 CPU 关闭并计算每行的长度。len(TrackNo)
0赞
Charlieface
10/27/2023
@Stuckat1337长度存储在前缀中,它不仅仅是以 null 结尾的 C 字符串。
0赞
Charlieface
10/27/2023
可以通过将重复的计算放入一系列CROSS APPLY (VALUES
0赞
Stuck at 1337
10/27/2023
@Charlieface 与常数相比,您是说 LEN() 是零成本吗?无论是实际计算长度还是从页面中检索长度,它仍然不是免费的,除了可能保护您免受未来数据类型更改的影响外,它不会给你带来任何东西。
0赞
Charlieface
10/27/2023
@Stuckat1337 不,我是说它不能做任何事情,比如读取整个字符串。长度已在内存中,它存储在字符串的其余部分(如 BSTR 或 .Net 字符串)旁边。这不是零成本,但成本并没有那么高。我同意没有必要。
-2赞
John Cappelletti
10/27/2023
#3
只是另一个选项,使用 和string_split()
string_agg()
例
Declare @YourTable Table ([SomeCol] varchar(50)) Insert Into @YourTable Values
('8070444981-010023-013123-INBBTC-C')
,('601724-072923-078923-INAAAX-B')
Select *
from @YourTable
Cross Apply ( Select NewVal =string_agg(value,'-') within group (order by ordinal)
From string_split(SomeCol,'-',1)
Where ordinal>3
) B
结果
SomeCol NewVal
8070444981-010023-013123-INBBTC-C INBBTC-C
601724-072923-078923-INAAAX-B INAAAX-B
评论
1赞
Xedni
10/27/2023
作为对 OP 的说明,这仅在运行 SQL Server 2022、Azure SQL 数据库、Azure SQL 托管实例或 Azure Synapse Analytics 时有效。
0赞
Xabi
10/27/2023
#4
with [table] (Trackno) as (
select '8070444981-010023-013123-INBBTC-C' union
select '601724-072923-078923-INAAAX-B')
select substring(Trackno,
0 + charIndex('-', TrackNo,
1 + charIndex('-', TrackNo,
2 + charIndex('-', Trackno)))
, 20) as [Result]
from [table]
评论
(charindex('-', TrackNo , 1)) +