我的数据库中有一对表 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
以一种费力的方式做到这一点但我认为(希望?)有更好的方法。你觉得怎么样?
答案 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倍)