1

I am trying to extract a specifc part from a string in MySQL, however, I am unable to extract it correctly.

The pattern is the following:

-MB|{field_1}-AA|{field_2}-BB|{field_3}

This is the example

-MB|string1-AA|string2-BB|string3

I've written the following code to extract the last field, however it is not dynamic, and will only work, when we have a specific number of letters/numbers:

SELECT 
    test_string,
    SUBSTRING(test_string, LOCATE( '|', test_string) + 1 - LOCATE( '|', test_string) - 9) as string3
FROM test_table;

The output is the whole string and then just the last part of it:

string3

Having this said, can someone suggest a syntax that I can use in order to extract:

  • the values between the 1st | and second |
  • the value between the 2nd | and the 3rd |
  • and a better way to extract everything after the 3rd |

Thank you in advance!

Ergest Basha
  • 7,870
  • 4
  • 8
  • 28
NikitaN
  • 11
  • 1
  • 2
    This probably answers your question: https://stackoverflow.com/questions/14347581/mysql-second-or-third-index-of-in-string – NickW Feb 06 '22 at 20:30
  • *extract the last field* `SUBSTRING_INDEX(column, '|', -1)` – Akina Feb 06 '22 at 20:35

1 Answers1

0

If you're going for the last string only, you can REVERSE() the string first then locate | and then use it to do SUBSTRING() on the reversed string.. THEN reverse it again to get the original string. There are three REVERSE() in total if you're going with SUBSTRING() without a subquery:

SELECT test_string,
       REVERSE(SUBSTRING(REVERSE(test_string),1,LOCATE('|',REVERSE(test_string))-1))
 FROM test_table;

If you're using a subquery, you can reduce the usage of REVERSE() to two, albeit with a longer query:

SELECT test_string,
       REVERSE(SUBSTRING(rvstr,1,LOCATE('|',rvstr)-1))
  FROM
(SELECT test_string,
       REVERSE(test_string) rvstr
 FROM test_table) a;

But you can avoid all that and just use SUBSTRING_INDEX

SELECT test_string,
       SUBSTRING_INDEX(test_string, '|', -1)
 FROM test_table;

You can use the same function to extract other string separated by the delimiter using something like this:

SELECT test_string,
       SUBSTRING_INDEX(SUBSTRING_INDEX(test_string,'|',1),'|',-1) AS 'Str1',
       SUBSTRING_INDEX(SUBSTRING_INDEX(test_string,'|',2),'|',-1) AS 'Str2',
       SUBSTRING_INDEX(SUBSTRING_INDEX(test_string,'|',3),'|',-1) AS 'Str3'
 FROM test_table;

As for "way to extract everything after the 3rd", I think it's a bit tricky but maybe:

SELECT test_string,
        Str1,Str2,Str3,
        SUBSTRING(test_string,LENGTH(CONCAT(Str1,Str2,Str3))+4) AS 'StrAfter3rd'
 FROM
(SELECT test_string,
       SUBSTRING_INDEX(SUBSTRING_INDEX(test_string,'|',1),'|',-1) AS 'Str1',
       SUBSTRING_INDEX(SUBSTRING_INDEX(test_string,'|',2),'|',-1) AS 'Str2',
       SUBSTRING_INDEX(SUBSTRING_INDEX(test_string,'|',3),'|',-1) AS 'Str3'
 FROM test_table) v;

Getting the LENGTH() of the concatenated results of Str1 to Str3 with 3 of the original | re-added and + the last | before the 4th string (+4 in total), then use it for the SUBSTRING().

Demo fiddle

FanoFN
  • 6,815
  • 2
  • 13
  • 33