выбрать и объединить все до и после определенного символа - PullRequest
0 голосов
/ 13 марта 2020

У меня есть строка типа AAAA.BBB.CCCC.DDDD.01.A, и я пытаюсь манипулировать этим и в итоге получаю AAAA-BBB

Я добился этого, написав этот спорный кусок кода

declare @string varchar(100) = 'AAAA.BBB.CCCC.DDDD.01.A'
select replace(substring(@string,0,charindex('.',@string)) + substring(@string,charindex('.',@string,CHARINDEX('.',@string)),charindex('.',@string,CHARINDEX('.',@string)+1)-charindex('.',@string)),'.','-')

Есть ли другой способ сделать это более элегантным и читабельным?

Я смотрел на некоторые string_split операции, но не могу обернуться вокруг него.

Ответы [ 3 ]

1 голос
/ 13 марта 2020

Если вы открыты для каких-либо преобразований JSON, вам подойдет следующий подход. Вам необходимо преобразовать текст в действительный массив JSON (AAAA.BBB.CCCC.DDDD.01.A преобразуется в ["AAAA","BBB","CCCC","DDDD","01","A"]) и получить необходимые элементы из этого массива, используя JSON_VALUE():

Оператор:

DECLARE @string varchar(100) = 'AAAA.BBB.CCCC.DDDD.01.A'
SET @string = CONCAT('["', REPLACE(@string, '.', '","'), '"]')
SELECT CONCAT(JSON_VALUE(@string, '$[0]'), '-', JSON_VALUE(@string, '$[1]'))

Результат:

AAAA-BBB

Примечания: При таком подходе вы можете легко получить доступ ко всем деталям из входной строки по индексу (на основе 0).

1 голос
/ 13 марта 2020

Я думаю, что это немного чище:

declare @string varchar(100) = 'AAAA.BBB.CCCC.DDDD.01.A'
select 
  replace( -- replace '.' with '-' (A)
      substring(@string, 1 -- in the substring of @string starting at 1 
          ,charindex('.', @string -- and going through 1 before the index of '.'(B)
            ,charindex('.',@string)+1) -- that is after the first index of the first '.' 
           -1) -- (B)
    ,'.','-') -- (A)
0 голосов
/ 13 марта 2020

В зависимости от того, что находится в вашей строке, вы можете злоупотребить PARSENAME. Предназначен для разбиения имен вроде adventureworks.dbo.mytable.mycolumn. Он работает следующим образом:

DECLARE @x as VARCHAR(100) = 'aaaa.bbb.cccc.ddddd'

SELECT CONCAT( PARSENAME(@x,4), '-', PARSENAME(@x,3) ) 

. Вы также можете посмотреть комбинацию STUFF, чтобы удалить первый '.' и замените на '-', затем оставьте результат по индексу следующего '.' но вряд ли это будет лучше, чем это или предложение Кевина. Использование разбиения строк, вероятно, будет слишком громоздким:

SELECT CONCAT(MAX(CASE WHEN rn = 1 THEN v END), '-', MAX(CASE WHEN rn = 2 THEN v END)) 
FROM (
  SELECT row_number () over (order by (select 0)) rn, value as v 
  FROM string_split(@x,'.')
) y WHERE rn IN (1,2)

Поскольку строка разбивается на строки, которые затем необходимо пронумеровать, чтобы отфильтровать и вытащить части ты хочешь. Это также зависит от строк, выходящих из разделения строк в порядке, в котором они были в исходной строке, , что MS не гарантирует, будет иметь место

...