简体   繁体   中英

Extracting values from (multiple) brackets in one string

Here's what I would like to do with MySQL (MariaDB). I want to retrieve a substring of the contents between curly brackets (let's call them tags) in the column 'Case_Title'. My table looks like this.

Table: cases

| Case_ID | Case_Title                       | Department  |
|---------|----------------------------------|-------------|
| 7032389 | {RJ1} Not able to connect        | Consumer    |
| 7243040 | {RJ2}{ZO}{WAD} Connection issues | Business    |
| 7249910 | {O2A} No incoming mgs {WAD}      | Consumer    |
|---------|----------------------------------|-------------|

By searching Stack Overflow I came up with two options to retrieve these substrings.

1 - Using regular expressions. Since I'm on MariaDB so I can use REGEXP_SUBSTR, REGEXP_INSTR, REGEXP_REPLACE .

SELECT Case_ID, REGEXP_SUBSTR(Case_title,'{(.*?)}') as 'Tag'
FROM cases

2 - combinations of SUBSTR() and INSTR() .

SELECT Case_ID, SUBSTR(Case_Title,INSTR(Case_Title,"{"), INSTR(Case_Title,"}") - INSTR(Case_Title,"{") + 1) as 'Tag'
FROM cases

Both options will output:

| Case_ID | Tag   |
|---------|-------|
| 7032389 | {RJ1} |
| 7243040 | {RJ2} |
| 7249910 | {O2A} |
|---------|-------|

However, the other 'tags' in the Case_Title are ignored. I just cannot seem to find a way to get the output like this:

| Case_ID | Tag   |
|---------|-------|
| 7032389 | {RJ1} |
| 7243040 | {RJ2} |
| 7243040 | {ZO}  |
| 7243040 | {WAD} |
| 7249910 | {O2A} |
| 7249910 | {WAD} |
|---------|-------|

Please note that I'd like to have new records/rows for each tag, rather than concatenating them like: {RJ1},{ZO},{WAD} . Also, I don't know in advance:

  • how many tags a title will contain.
  • where the tags are located in the Case_Title.
  • if all tags are grouped together or if they're scattered across the Case_Title.
  • the actual contents of the tag themselves.

Using a combination of functions this works by first pivoting the data, separating them by }{ , this then gets each value on its own line. From there I removed all values after the first } . Some concatenation was needed to restore lost brackets removed in the pivoting.

SELECT Case_ID,
CONCAT(substring_index(CASE WHEN RIGHT(CASE WHEN LEFT(tag,1) = '{' 
                                            THEN tag 
                                            ELSE CONCAT('{',tag) END,1) = '}' 
                            THEN CASE WHEN LEFT(tag,1) = '{' 
                                      THEN tag 
                                      ELSE CONCAT('{',tag) 
                                 END 
                            ELSE CONCAT(CASE WHEN LEFT(tag,1) = '{' 
                                             THEN tag 
                                             ELSE CONCAT('{',tag) 
                                        END,'}') 
                       END,'}',1),'}') AS tag
FROM (
SELECT DISTINCT Case_ID, SUBSTRING_INDEX(SUBSTRING_INDEX(Case_Title, '}{', n), '}{', -1) tag
FROM (SELECT 1 n 
      UNION ALL
      SELECT 2 
      UNION ALL 
      SELECT 3 
      UNION ALL
      SELECT 4 
      UNION ALL 
      SELECT 5) n 
INNER JOIN cases ON CHAR_LENGTH(Case_Title)-CHAR_LENGTH(REPLACE(Case_Title, '}{', ''))>=n-1) a

Input

Case_ID Case_Title                       Department
7032389 {RJ1} Not able to connect        Consumer
7243040 {RJ2}{ZO}{WAD} Connection issues Business
7249910 {O2A} No incoming mgs {WAD}      Consumer

Output

Case_ID tag
7032389 {RJ1}
7243040 {RJ2}
7249910 {O2A}
7243040 {ZO}
7243040 {WAD}

SQL Fiddle: http://sqlfiddle.com/#!9/0fa9c13/94/0

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