хочет строковый вывод, который находится между 5-м и 6-м '/' - PullRequest
1 голос
/ 05 августа 2020

Входные данные выглядят как

/nfs/site/disks/mtl_workdisk_003/mtlmedia/filter_bundle2846/regress/
/nfs/site/disks/mtl_workdisk_003/mtl3d/filter_bundle2846/regress/
/nfs/site/disks/mtl_workdisk_003/etl66/filter_bundle2846/regress/

Результат должен быть

mtlmedia
mtl3d
etl66

Я могу успешно получить результат, но есть ли способ упростить его с помощью других функций или методов?

declare @T table
(
InputString varchar(max)
);

insert into @T values
('/nfs/site/ssd/mtl_workdisk_1/mediatek/filter_candle46/regression/'),
('/nfs/location/disks/mtl_workdisk_003/mtl3d/filter_candle2846/regress/'),
('/nfs/place/disks/mtl_workdisk_003/etl1266/bundle2846/regress/') ;

select -- P1.Pos, P2.Pos, P3.Pos,P4.Pos,P5.Pos,P6.Pos,
substring(InputString, P5.Pos + 1, P6.Pos - P5.Pos - 1) as OutputString
from @T
cross apply (select (charindex('/', InputString))) as P1(Pos)
cross apply (select (charindex('/', InputString, P1.Pos+1))) as P2(Pos)
cross apply (select (charindex('/', InputString, P2.Pos+1))) as P3(Pos)
cross apply (select (charindex('/', InputString, P3.Pos+1))) as P4(Pos)
cross apply (select (charindex('/', InputString, P4.Pos+1))) as P5(Pos)
cross apply (select (charindex('/', InputString, P5.Pos+1))) as P6(Pos) ;

Ответы [ 2 ]

2 голосов
/ 05 августа 2020

Подходы, основанные на встроенной поддержке XML или JSON, являются возможными вариантами:

Заявление, основанное на XML:

SELECT CAST('<x>' + REPLACE(InputString, '/', '</x><x>') + '</x>' AS XML).value('/x[6]','varchar(max)')
FROM @t

Заявление, основанное на JSON:

SELECT JSON_VALUE(CONCAT('["', REPLACE(InputString, '/', '","'), '"]'), '$[5]')
FROM @T

Результат:

mediatek
mtl3d
etl1266

Примечания:

JSON поддержка доступна с SQL Server 2016.

1 голос
/ 05 августа 2020

Если вы всегда знаете root пути и просто хотите получить имя первой подпапки после этого, вы можете получить подстроку на основе длины root в сочетании с charindex для поиска первого sla sh после root.

declare @paths as table(fullpath varchar(max))

insert into @paths values ('/nfs/site/disks/mtl_workdisk_003/mtlmedia/filter_bundle2846/regress/')
insert into @paths values ('/nfs/site/disks/mtl_workdisk_003/mtl3d/filter_bundle2846/regress/')
insert into @paths values ('/nfs/site/disks/mtl_workdisk_003/etl66/filter_bundle2846/regress/')

declare @root as varchar(max) = '/nfs/site/disks/mtl_workdisk_003/'
declare @startPos as int = len(@root) + 1

select substring(fullpath, @startPos, CHARINDEX('/',fullpath,@startPos) - @startPos) filename
from @paths
where CHARINDEX('/',fullpath,@startPos) > 0

Я сделал предложение where в конце, чтобы предотвратить любые ошибки, если по какой-то причине после root. * не найдена подпапка (sla sh) 1004 *

Если вы всегда знаете и конец пути, вы можете просто использовать REPLACE, чтобы удалить окончание, и даже не искать "/" с помощью CHARINDEX.

...