Separação em String em 2 Campos - Sem quebra de palavras

SQL

Firebird

12/04/2024

Olá pessoal! Sou nova aqui no fórum! Gostaria muito de uma ajuda de vocês!
Tenho um campo em um select, e eu gostaria de dividir ele em dois campos. Esses campos tem um tamanho de 30 caracteres.
Usei um SUBSTRING, mas ele acaba quebrando as palavras.
O que eu gostaria é que, se quando estiver no final da string, a palavra dor cortada, gostaria que essa palavra fosse para o segundo campo, Assim:

No select estou usando o SUBSTRING assim (detalhe.. é um campo concatenado):
substring(ic.itc_fio_ret ||'-'||Fio.Fio_Descricao from 1 for 30) as Fio1,
substring(ic.itc_fio_ret ||'-'||Fio.Fio_Descricao from 31 for 51) as Fio2,



Exemplo 1:
Palavra completa: 289-FIO 20/1 100% CO TINTO JADE

com o SUBSTRING fica assim:
Fio1: 289-FIO 20/1 100% CO TINTO JAD
Fio2: E

Nesse caso eu gostaria que ficasse assim:
Fio1: 289-FIO 20/1 100% CO TINTO
Fio2: JADE

Exemplo 2:
Palavra Completa: 290-FIO 20/1 100% CO TINTO PINK FORTE-4727

com o SUBSTRING fica assim:
Fio1: 290-FIO 20/1 100% CO TINTO PIN
Fio2: K FORTE-4727

Nesse caso eu gostaria que ficasse assim:
Fio1: 290-FIO 20/1 100% CO TINTO
Fio2: PINK FORTE-4727


Como eu poderia fazer nesse caso?
Se quiserem, posso postar aqui o meu select completo
Francielle

Francielle

Curtidas 0

Melhor post

Arthur Heinrich

Arthur Heinrich

15/04/2024

Para fazer isso é necessário fazer algumas gambiarras.

A ideia central é quebrar a string em um espaço em branco.

Se você só possui 30 caracteres, precisa encontrar o último espaço até a posição 31. Se ele aparecer na posição 31, os 30 caracteres anteriores caberão perfeitamente no espaço.

O problema é encontrar a posição do espaço.

O SQL Server possui uma função chamada CHARINDEX()

Exemplo: CHARINDEX(' ', ic.itc_fio_ret ||'-'||Fio.Fio_Descricao) encontrará o primeiro espaço em branco no texto.

Porém, queremos o último. Para isso, podemos utilizar também as funções SUBSTRING() e REVERSE()

Então, podemos fazer o seguinte.

1 - recortamos os primeiros 31 caracteres da sua string, para procurar o último espaço

substring(ic.itc_fio_ret ||'-'||Fio.Fio_Descricao, 1, 31)

2 - invertemos a sequência de caracteres usando a função reverse.

reverse( substring(ic.itc_fio_ret ||'-'||Fio.Fio_Descricao, 1, 31) )

3 - procuramos o primeiro espaço

charindex(' ', reverse( substring(ic.itc_fio_ret ||'-'||Fio.Fio_Descricao, 1, 31) ) )

4 - com a posição dele, fazemos um cálculo para identificar a posição real na string de origem

Se achar na posição 1, significa que está na posição 31. Se achar na 2, é porque está na 30 e assim por diante. Logo, a posição será:

32 - charindex(' ', reverse( substring(ic.itc_fio_ret ||'-'||Fio.Fio_Descricao, 1, 31) ) )

Logo, a primeira string será:

linha 1: substring( ic.itc_fio_ret ||'-'||Fio.Fio_Descricao, 1, 32 - charindex(' ', reverse( substring(ic.itc_fio_ret ||'-'||Fio.Fio_Descricao, 1, 31) ) ) - 1)

Para pegar a linha 2, basta pegar a partir do espaço:

linha 2: substring( ic.itc_fio_ret ||'-'||Fio.Fio_Descricao, 32 - charindex(' ', reverse( substring(ic.itc_fio_ret ||'-'||Fio.Fio_Descricao, 1, 31) ) ) + 1, 30)

Com isso, dividimos a string em 2. Porém, pode ser que o código tenha menos de 31 caracteres, não necessitando da quebra, ou, pode ser que tenha mais de 60 caracteres, necessitando de 3 ou mais quebras.

Supondo que tenha apenas zero ou uma quebra, precisamos fazer um cálculo condicional:

coluna 1:

case len( ic.itc_fio_ret ||'-'||Fio.Fio_Descricao ) <= 30
  then
    ic.itc_fio_ret ||'-'||Fio.Fio_Descricao
  else
    substring( ic.itc_fio_ret ||'-'||Fio.Fio_Descricao, 1, 32 - charindex(' ', reverse( substring(ic.itc_fio_ret ||'-'||Fio.Fio_Descricao, 1, 31) ) ) - 1)
  end


coluna 2:

case len( ic.itc_fio_ret ||'-'||Fio.Fio_Descricao ) <= 30
  then
    ''
  else
    substring( ic.itc_fio_ret ||'-'||Fio.Fio_Descricao, 32 - charindex(' ', reverse( substring(ic.itc_fio_ret ||'-'||Fio.Fio_Descricao, 1, 31) ) ) + 1, 30)
  end

GOSTEI 1

Mais Respostas

Emerson Nascimento

Emerson Nascimento

12/04/2024

resposta PERFEITA do Arthur Heinrich

segue a tradução para o FB:
    case when character_length('290-FIO 20/1 100% CO TINTO PINK FORTE-4727') <= 30
    then
      '290-FIO 20/1 100% CO TINTO PINK FORTE-4727'
    else
      substring('290-FIO 20/1 100% CO TINTO PINK FORTE-4727' from 1 for 32 - position(' ', reverse(substring('290-FIO 20/1 100% CO TINTO PINK FORTE-4727' from 1 for 31) ) ) - 1)
    end Fio1,

    case when character_length('290-FIO 20/1 100% CO TINTO PINK FORTE-4727') <= 30
    then
      ''
    else
      substring('290-FIO 20/1 100% CO TINTO PINK FORTE-4727' from 32 - position(' ', reverse(substring('290-FIO 20/1 100% CO TINTO PINK FORTE-4727' from 1 for 31) ) ) + 1 for 20)
    end Fio2



GOSTEI 0
POSTAR