从一个字符串中的(多个)括号中提取值

时间:2017-11-15 11:32:54

标签: mysql sql

这就是我想用MySQL(MariaDB)做的事情。我想在列' Case_Title'中检索大括号之间的内容的子字符串(让我们称之为标记)。我的表看起来像这样。

表:案例

| 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    |
|---------|----------------------------------|-------------|

通过搜索Stack Overflow,我提出了两个选项来检索这些子字符串。

1 - 使用正则表达式。因为我在MariaDB上,所以我可以使用 REGEXP_SUBSTR,REGEXP_INSTR,REGEXP_REPLACE

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

2 - SUBSTR() INSTR()的组合。

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

两个选项都会输出:

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

然而,其他标签'在Case_Title中被忽略。我似乎无法找到一种方法来获得这样的输出:

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

请注意,我希望每个标记都有新的记录/行,而不是像{RJ1},{ZO},{WAD}那样连接它们。另外,我事先并不知道:

  • 标题将包含多少个标记。
  • 标签位于Case_Title中。
  • 如果所有代码组合在一起,或者它们分散在Case_Title中。
  • 标签本身的实际内容。

1 个答案:

答案 0 :(得分:0)

使用功能组合,首先通过旋转数据,将它们分开}{,然后将每个值放在自己的行上。从那里我删除了第一个}之后的所有值。需要一些连接来恢复在旋转中删除的丢失的括号。

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

输入

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

输出

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

SQL小提琴:http://sqlfiddle.com/#!9/0fa9c13/94/0