7

I trying extract last words from my string.

Example

Input String : GGG_FFFF_AAAA_BBBBBB_CCC_DDDDD

Result

╔═══════════╦════════════╗
║ FIRST_COL ║ SECOND_COL ║
╠═══════════╬════════════╣
║ CCC       ║ DDDDD      ║
╚═══════════╩════════════╝

I have the below code working.

DECLARE @STR VARCHAR(50) = 'GGG_FFFF_AAAA_BBBBBB_CCC_DDDDD'

SELECT 
Reverse(LEFT(Stuff(Reverse(@STR), 1, Charindex('_', Reverse(@STR)) + 1 - 1, ''), Charindex('_', Stuff(Reverse(@STR), 1, Charindex('_', Reverse(@STR)) + 1 - 1, '')) - 1)) as FIRST_COL,
Reverse(LEFT(Reverse(@STR), Charindex('_', Reverse(@STR)) - 1)) as SECOND_COL

Is there any simpler to achieve this

Pரதீப்
  • 91,748
  • 19
  • 131
  • 172
  • Possible duplicate of [How to split a comma-separated value to columns](http://stackoverflow.com/questions/10581772/how-to-split-a-comma-separated-value-to-columns) – Mladen Oršolić Sep 28 '16 at 10:28

5 Answers5

6

You can use XML:

DECLARE @input nvarchar(max) = 'GGG_FFFF_AAAA_BBBBBB_CCC_DDDDD',
        @x xml

SELECT @x = CAST('<a>'+REPLACE(REVERSE(@input),'_','</a><a>')+'</a>' as xml)


SELECT  REVERSE(@x.value('/a[2]','nvarchar(max)')) as FIRST_COL,
        REVERSE(@x.value('/a[1]','nvarchar(max)')) as SECOND_COL

Output:

FIRST_COL   SECOND_COL
CCC         DDDDD
gofr1
  • 15,741
  • 11
  • 42
  • 52
3

You can use PARSENAME (starting with 2012)

DECLARE @Val NVARCHAR(100)= 'AAAA_BBB_CCC_DDDDD'
SELECT PARSENAME(REPLACE(@Val, '_', '.'), 1) -- DDDDD
SELECT PARSENAME(REPLACE(@Val, '_', '.'), 2) -- CCC

Note: This is not correct for more than 3 _

neer
  • 4,031
  • 6
  • 20
  • 34
2
Declare @Var1  VARCHAR(MAX)='AAAA_BBB_CCC_DDDDDDD'

----SELECT CHARINDEX('_',REVERSE(@Var1))
SELECT RIGHT(@Var1,CHARINDEX('_',REVERSE(@Var1))-1)


-----SELECT REPLACE(@Var1,RIGHT(@Var1,CHARINDEX('_',REVERSE(@Var1))),'')

--SELECT CHARINDEX('_',REVERSE(
--  REPLACE(@Var1,RIGHT(@Var1,CHARINDEX('_',REVERSE(@Var1))),'')
--))

SELECT RIGHT(
REPLACE(@Var1,RIGHT(@Var1,CHARINDEX('_',REVERSE(@Var1))),''),
CHARINDEX('_',REVERSE(
    REPLACE(@Var1,RIGHT(@Var1,CHARINDEX('_',REVERSE(@Var1))),'')
))-1)
1

You can use a user defined custom function as follows

DECLARE @Val NVARCHAR(100)= 'AAAA_BBB_CCC_DDDDD'
;with cte as (
    select id, val, MAX(id) over (partition by 1) maximum 
    from dbo.SQLSplitString(@Val,'_',1,0) t
)
select val from cte where id >= maximum - 1

You can find the SQL split function codes here

Eralper
  • 6,461
  • 2
  • 21
  • 27
1

Try this : While storing string, store it as revers that reduces the UN-neccessary calls to make string reverse

DECLARE @STR VARCHAR(50) =REVERSE('GGG_FFFF_AAAA_BBBBBB_CCC_DDDDD')

SELECT REVERSE(SUBSTRING(@STR,0, CHARINDEX('_',@STR))),
       REVERSE(SUBSTRING(@STR,CHARINDEX('_',@STR,CHARINDEX('_',@STR))+1,3))
Pரதீப்
  • 91,748
  • 19
  • 131
  • 172
Jaydip Jadhav
  • 12,179
  • 6
  • 24
  • 40