MySQL - 如何从字符串接收子字符串表
Posted
技术标签:
【中文标题】MySQL - 如何从字符串接收子字符串表【英文标题】:MySQL - How to recieve table of substrings from string 【发布时间】:2016-07-04 12:41:31 【问题描述】:我在我的数据库中得到了一个表,其中包含一对 EVENT_ID - ATTENDANTS varchar(300) 包含从重复属性和唯一用户名连接的字符串形式的数据。 属性和名称之间的分隔符是“:”,并且每个“属性:用户”集合都以“;”结尾某些属性名称中有空格。每行中的对数未知。
“属性C:user_name1;属性A:user_name3;属性A:user_name4;属性A:user_name10;属性B:user_name42;”
然后我得到了带有 USER_ID - USER_NAME 对的表和带有字段 USER_ID - EVENT_ID - ATTRIBUTE 的目标表。
提取用户和属性并将它们插入目标表的最佳方法是什么?
我很想在 SQL (mysql) 中执行此操作,以防使用函数等,使它们成为临时的,脚本将只运行一次。
如果它太复杂,我愿意将 php 与 OOP mysqli 函数一起使用。 (它将在一组其他 $mysqli->query() 命令中运行)
我发现,MySQL functionsSUBSTRING()、LOCATE()、LENGTH() 可以派上用场。
我可以通过 PHP 以某种费力的方式做到这一点
-
根据 SELECT(USER_ID - USER_NAME) 制作数组
进行 SELECT(EVENT_ID - ATTENDANTS) 并为每一行调用explode(),
获取属性、EVENT_ID、USER_ID(来自上面的数组,而不是 SQL
查询每个事件的每个字符串中的每个用户名)
在准备好的mysqli的情况下将数据并行插入到目标表中
声明
但我认为(希望?)有更好的方法。你怎么看?
【问题讨论】:
【参考方案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
子查询即可获得更多对。
【讨论】:
我想:t.col = my_table.ATTENDANTS, n = 重复次数,n.n 到底是什么?我必须补充一点,对的数量是未知的,而且很可能每条 EVENT 行都不同。 @Faramos 。 . .on
子句应该处理这个问题。您只需要足够大的 n
值来获取每一对。【参考方案2】:
经过一番研究,我解决了它,它并不像看起来那样愚蠢。
代码优先:
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 ... != ' ' 过滤那些空行
这当然不是正确的方法,但在 150 行最多 23 对的情况下,它运行得非常好而且很快(仅比该表上的基本选择慢 10 倍)
【讨论】:
以上是关于MySQL - 如何从字符串接收子字符串表的主要内容,如果未能解决你的问题,请参考以下文章