将分隔的字符串转换为mysql中的多个值

epo*_*epo 6 mysql sql

我有一个mysql遗留表,其中包含客户端标识符和项目列表,后者作为逗号分隔的字符串.例如"xyz001", "foo,bar,baz".这是遗留的东西,用户坚持能够编辑逗号分隔的字符串.

他们现在要求将上面的报告表分成不同的行,例如

"xyz001", "foo"
"xyz001", "bar"
"xyz001", "baz"
Run Code Online (Sandbox Code Playgroud)

将字符串分解为子字符串很容易实现,我已经编写了一个程序来创建一个单独的表,但这需要触发器来处理删除,更新和插入.这个查询很少需要(例如每月一次),但在运行时必须是绝对最新的,因此例如不保证触发器的开销,并且创建表的计划任务可能不够及时.

有没有办法写一个函数来返回一个表或一组,以便我可以根据需要加入标识符和各个项目?

Sen*_*ful 4

这称为走字符串。以下是如何使用所提供的规格进行操作的示例:

您需要创建一个表,其中包含与字段长度 + 1 一样多的整数。因此,如果字段长度为 255,则您将需要 256 条记录,其中仅包含 0-255 之间的单个数字。

int_table:

+---+
| i |
+---+
| 0 |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
+---+
Run Code Online (Sandbox Code Playgroud)

接下来,您将需要一个查询来连接该表并检查该位置是否存在逗号。(我分别legacy_table用字段client和来调用您的表items。)

select 
  legacy_table.client, 
  substring(
    legacy_table.items, 
    int_table.i + 1, 
    if(
      locate(',', legacy_table.items, int_table.i + 1) = 0, 
      length(legacy_table.items) + 1, 
      locate(',', legacy_table.items, int_table.i + 1)
    ) - (int_table.i + 1)
  ) as item
from legacy_table, int_table
where legacy_table.client = 'xyz001'
  and int_table.i < length(legacy_table.items)
  and (
    (int_table.i = 0) 
    or (substring(legacy_table.items, int_table.i, 1) = ',')
  )
Run Code Online (Sandbox Code Playgroud)

对于您实际使用它来说,它可能不够高效,但我想我应该将它作为一个示例来展示,以便您知道可用的内容。