SQL 不同长度的 SUBSTRING 和 PATINDEX
SQL SUBSTRING & PATINDEX of varying lengths
SQL 服务器 2017.
给定以下 3 条记录,其字段类型为 nvarchar(250)
,称为 fileString
:
_318_CA_DCA_2020_12_11-01_00_01_VM6.log
_319_CA_DCA_2020_12_12-01_VM17.log
_333_KF_DCA01_00_01_VM232.log
我想 return:
VM6
VM17
VM232
到目前为止尝试过:
SELECT
SUBSTRING(fileString, PATINDEX('%VM[0-9]%', fileString), 3)
FROM dbo.Table
但当然只有 return 个 VM 和 1 个号码。
当字符数变化时,我该如何定义参数?
编辑:先发制人地回答可能出现的问题,是的,VM 模式将始终由.log
立即进行,没有别的。但即使我采用这种方法并向后工作,我仍然不明白如何定义数字变化时要采用的字符数。
你的长度一开始是一致的。所以远离 patindex
并使用 substring
来裁剪开头。然后只需在末尾用空字符串替换'.log'即可。
select *,
part = replace(substring(filestring,33,255),'.log','')
from table;
编辑:
好的,根据您的编辑,您显示了不同的前缀部分。那么 patindex
实际上是正确的。这是我的解决方案,它并不比其他答案好或坏,但不同之处在于它避免 reverse
并将 patindex 计算委托给交叉应用部分。您可能会发现它更具可读性。
select filestring,
part = replace(substring(filestring, ap.vmIx, 255),'.log','')
from table
cross apply (select
vmIx = patindex('%_vm%', filestring) + 1
) ap
这是一种方法:
DECLARE @test TABLE( fileString varchar(500))
INSERT INTO @test VALUES
('_318_CA_DCA_2020_12_11-01_00_01_VM6.log')
,('_319_CA_DCA_2020_12_12-01_00_01_VM17.log')
,('_333_KF_DCA_2020_12_15-01_00_01_VM232.log')
-- 5 is the length of file extension + 1 which is always the same size '.log'
SELECT
REVERSE(SUBSTRING(REVERSE(fileString),5,CHARINDEX('_',REVERSE(fileString))-5))
FROM @test AS t
这将动态获取最后一个 _ 的长度和位置并删除 .log。
这不是最有效的,如果您能够使用 C# 编写一个 CLR 函数并将其导入到 SQL,那将更有效。或者您可以以此为起点并根据需要进行调整。
您可以删除变量并将其替换为您的 table,如下所示
DECLARE @TESTVariable as varchar(500)
Set @TESTVariable = '_318_CA_DCA_2020_12_11-01_00_01_VM6adf.log'
SELECT REPLACE(SUBSTRING(@TESTVariable, PATINDEX('%VM[0-9]%', @TESTVariable), PATINDEX('%[_]%', REVERSE(@TESTVariable))), '.log', '')
select *,
part = REPLACE(SUBSTRING(filestring, PATINDEX('%VM[0-9]%', filestring), PATINDEX('%[_]%', REVERSE(filestring))), '.log', '')
from table
SQL 服务器 2017.
给定以下 3 条记录,其字段类型为 nvarchar(250)
,称为 fileString
:
_318_CA_DCA_2020_12_11-01_00_01_VM6.log
_319_CA_DCA_2020_12_12-01_VM17.log
_333_KF_DCA01_00_01_VM232.log
我想 return:
VM6
VM17
VM232
到目前为止尝试过:
SELECT
SUBSTRING(fileString, PATINDEX('%VM[0-9]%', fileString), 3)
FROM dbo.Table
但当然只有 return 个 VM 和 1 个号码。
当字符数变化时,我该如何定义参数?
编辑:先发制人地回答可能出现的问题,是的,VM 模式将始终由.log
立即进行,没有别的。但即使我采用这种方法并向后工作,我仍然不明白如何定义数字变化时要采用的字符数。
你的长度一开始是一致的。所以远离 patindex
并使用 substring
来裁剪开头。然后只需在末尾用空字符串替换'.log'即可。
select *,
part = replace(substring(filestring,33,255),'.log','')
from table;
编辑:
好的,根据您的编辑,您显示了不同的前缀部分。那么 patindex
实际上是正确的。这是我的解决方案,它并不比其他答案好或坏,但不同之处在于它避免 reverse
并将 patindex 计算委托给交叉应用部分。您可能会发现它更具可读性。
select filestring,
part = replace(substring(filestring, ap.vmIx, 255),'.log','')
from table
cross apply (select
vmIx = patindex('%_vm%', filestring) + 1
) ap
这是一种方法:
DECLARE @test TABLE( fileString varchar(500))
INSERT INTO @test VALUES
('_318_CA_DCA_2020_12_11-01_00_01_VM6.log')
,('_319_CA_DCA_2020_12_12-01_00_01_VM17.log')
,('_333_KF_DCA_2020_12_15-01_00_01_VM232.log')
-- 5 is the length of file extension + 1 which is always the same size '.log'
SELECT
REVERSE(SUBSTRING(REVERSE(fileString),5,CHARINDEX('_',REVERSE(fileString))-5))
FROM @test AS t
这将动态获取最后一个 _ 的长度和位置并删除 .log。
这不是最有效的,如果您能够使用 C# 编写一个 CLR 函数并将其导入到 SQL,那将更有效。或者您可以以此为起点并根据需要进行调整。
您可以删除变量并将其替换为您的 table,如下所示
DECLARE @TESTVariable as varchar(500)
Set @TESTVariable = '_318_CA_DCA_2020_12_11-01_00_01_VM6adf.log'
SELECT REPLACE(SUBSTRING(@TESTVariable, PATINDEX('%VM[0-9]%', @TESTVariable), PATINDEX('%[_]%', REVERSE(@TESTVariable))), '.log', '')
select *,
part = REPLACE(SUBSTRING(filestring, PATINDEX('%VM[0-9]%', filestring), PATINDEX('%[_]%', REVERSE(filestring))), '.log', '')
from table