简体   繁体   中英

What is the best way to convert this to SQL

I know for the Database Guru's here this should be a doddle. I have a Field in my database in the format of ' A/B/C/D/E/F '

The format is irrelevant I generally need the last two parts so for the above it would be

'EF'

But if I had another string

AB/CD/EF/GH == EFGH

And I am looking to getting the last two parts to return like this 'EFGH'

Does anyone know an SQL Function I can do that will split this

I am using Microsoft SQL Server 2012 - I Hope this helps,

Here is C# Code.

var myText = "A/B/C/D/E/F";
var identificationArray = myText.Split('/');

if(identificationArray.Length >= 2)
{
    var friendlyId = identificationArray[identificationArray.Length - 2] + identificationArray[identificationArray.Length - 1];

    return friendlyId;
}
return "";

Here is one answer that searches a string in reverse order for the second forward slash and returns that substring with forward slashes removed:

declare @s varchar(20)
set @s = 'A/B/C/D/E/F'

-- result: 'EF'
select reverse(replace(left(reverse(@s), charindex('/', reverse(@s), charindex('/', reverse(@s)) + 1)), '/', ''))

set @s = 'AB/CD/EF/GH'

-- result: 'EFGH'
select reverse(replace(left(reverse(@s), charindex('/', reverse(@s), charindex('/', reverse(@s)) + 1)), '/', ''))

Testing this with a couple of other inputs:

set @s = '/AB/CD' -- result: 'ABCD'
set @s = 'AB/CD'  -- result: an empty string '' -- you may not want this result
set @s = 'AB'     -- result: an empty string ''

Here is a ridiculously complicated way to do the same thing with a series of common table expressions (CTEs). Credit goes to Itzik Ben-Gan for the CTE technique to generate a tally table using cross-joins:

declare @s varchar(50)
set @s = 'A/B/C/D/E/F/G'
--set @s = 'AB/CD/EF/GH'
--set @s = 'AB/CD'
--set @s = 'ABCD/EFGH/IJKL'
--set @s = 'A/B'
-- set @s = 'A'

declare @result varchar(50)
set @result = ''

;with
-- cross-join a meaningless set of data together to create a lot of rows
Nbrs_2    (n) AS (SELECT 1 UNION SELECT 0 ),
Nbrs_4    (n) AS (SELECT 1 FROM Nbrs_2     n1 CROSS JOIN Nbrs_2     n2),
Nbrs_16   (n) AS (SELECT 1 FROM Nbrs_4     n1 CROSS JOIN Nbrs_4     n2),
Nbrs_256  (n) AS (SELECT 1 FROM Nbrs_16    n1 CROSS JOIN Nbrs_16    n2),
Nbrs_65536(n) AS (SELECT 1 FROM Nbrs_256   n1 CROSS JOIN Nbrs_256   n2),
Nbrs      (n) AS (SELECT 1 FROM Nbrs_65536 n1 CROSS JOIN Nbrs_65536 n2),
-- build a table of numbers from the data above; this is insanely fast
nums(n) as
(
   select row_number() over(order by n) from Nbrs
),
-- split the string into separate rows per letter
letters(n, c) as
(
    select n, substring(@s, n, 1)
    from nums
    where n < len(@s) + 1
),
-- count the slashes from the rows in descending order
-- the important slash is the second one from the end
slashes(n, num) as
(
    select n, ROW_NUMBER() over (order by n desc)
    from letters
    where c = '/'
)
select @result = @result + c
from letters
where n > (select n from slashes where num = 2) -- get everything after the second slash
and c <> '/' -- and drop out the other slash

select @result

You need to reverse the string and find the 2nd occurrence of the / character. Once you have that it is pretty straight forward, just a lot of function calls to get the desired format

declare @test varchar(max);
set @test = 'b/b/a/v/d';

select 
    case
        when charindex('/', reverse(@test), charindex('/', reverse(@test))+1) = 0 then ''
        else replace(reverse(substring(reverse(@test), 0, charindex('/', reverse(@test), charindex('/', reverse(@test))+1))), '/', '')
    end

I understand that you want to do this in SQL. But did you think about using SQL CLR User Defined Functions? It will execute faster than SQL. you anyways have the logic implemented in C# which definitely simpler than the logic in SQL.

Late to the party, but here is my attempt:

declare @text varchar(max), @reversedtext varchar(max)

select @text = 'AB/CD/EF/GH'
select @reversedtext = reverse(@text)

declare @pos1 int
declare @pos2 int
declare @pos3 int


select @pos1 = charindex('/', @reversedtext)
select @pos2 = charindex('/', replace(@reversedtext, left(@reversedtext, @pos1), ''))
select @pos3 = @pos1 + @pos2

select REPLACE(RIGHT(@text, @pos3), '/', '')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM