MySQL - 如何从字符串中接收子字符串表

时间:2016-07-04 12:41:31

标签: mysql sql

我的数据库中有一对表 EVENT_ID - ATTENDANTS varchar(300),其中包含从重复属性和唯一用户名连接的字符串形式的数据。 属性和名称之间的分隔符是":"以及"属性的所有集合:user"结束于";"某些属性名称中有空格。每行中的对数量都是未知的。

" attributeC:USER_NAME1; attributeA:USER_NAME3; attributeA:user_name4; attributeA:user_name10; attributeB:user_name42; "

然后我得到了包含 USER_ID - USER_NAME 和目标表的表格,其中包含字段 USER_ID - EVENT_ID - ATTRIBUTE

提取用户和属性并将其插入目标表的最佳方法是什么?

我很乐意在SQL(MySQL)中执行此操作,如果使用函数等,使它们成为临时脚本,脚本将只运行一次。

如果它会变得非常复杂,我可以使用带有OOP mysqli函数的PHP。 (它将在其他$ mysqli-> query()命令集中运行)

我发现,MySQL functions SUBSTRING(),LOCATE(),LENGTH()可以派上用场。

我能够通过PHP

以一种费力的方式做到这一点
  1. 根据SELECT(USER_ID - USER_NAME)
  2. 制作数组
  3. 制作SELECT(EVENT_ID - ATTENDANTS)并为每一行调用explode(), get属性,EVENT_ID,USER_ID(来自上面的数组,而不是SQL 查询每个事件的每个字符串中的每个用户名)
  4. 在准备好mysqli的情况下,将数据并行地插入到目标表中 声明
  5. 但我认为(希望?)有更好的方法。你觉得怎么样?

2 个答案:

答案 0 :(得分:1)

你可以在MySQL中相当痛苦地做到这一点。以下是获取前三个这样的字符串的示例:

select t.col, n.n,
       substring_index(substring_index(t.col, ';', n.n), ';', -1) as pair,
       substring_index(substring_index(substring_index(t.col, ';', n.n), ';', -1), ':', 1) as name,
       substring_index(substring_index(substring_index(t.col, ';', n.n), ';', -1), ':', -1) as value
from t join
     (select 1 as n union all select 2 union all select 3
     ) n
     on length(t.col) - length(replace(t.col, ';', '') + 1 <= n.n;

您只需将其他数字添加到n子查询中即可获得更多对。

答案 1 :(得分:0)

经过一番研究,我解决了它并没有像它看起来那样愚蠢。

代码优先:

select OUTPUT.ID, OUTPUT.name, OUTPUT.attribute from
(
select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 1), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 1), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 2), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 2), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 3), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 3), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 4), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';',4), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 5), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 5), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 6), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 6), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 7), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 7), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 8), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 8), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 9), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 9), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 10), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 10), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 11), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 11), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 12), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 12), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 13), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 13), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 14), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 14), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 15), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 15), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 16), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 16), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 17), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 17), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 18), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 18), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 19), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 19), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 20), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 20), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 21), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 21), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 22), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 22), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 23), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 23), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 24), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 24), ';', -1), ':', -1) as name
from AKCE

union

select
  AKCE.ID,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 25), ';', -1), ':', 1) as attribute,
  substring_index(substring_index(substring_index(AKCE.PRIHLASENI, ';', 25), ';', -1), ':', -1) as name
from AKCE

order by ID
) AS OUTPUT WHERE OUTPUT.name!='' AND OUTPUT.attribute!=''

正如您所看到的,它很长,充满了冗余代码等。

当你使用位置大于定界数的substring_index()时,它将返回空字段。而且由于工会,每个原始表行(AKCE.ID)只返回一次空字段。

使用WHERE ...!=''

过滤这些空行

这当然不是正确的方法,但是在最多23对的150行上它的速度非常快(比该表上的基本选择慢10倍)