【问题标题】:Take a multi-delimited string in MySQL and convert to multiple records在 MySQL 中取一个多分隔的字符串并转换为多条记录
【发布时间】:2010-12-18 00:26:47
【问题描述】:

我正在将旧数据集转换为新结构化的数据库。目前他们有这种格式的数据:

[quantity int]~[var1 string]|[var2 string optional]|[var3 string optional];(etc);
[quantity]~[var1]|[var2]|[var3]

其中各种模式首先由分号分隔,然后由波浪号分隔,最后由现有数据库中同一字段(无括号)中的管道字符分隔。例如:

3~S|Red|Top;1~S|Blue|Top; ... etc ... ;20~XL|Green|Left

我想在每条记录中获取该字符串并执行以下操作:

  1. 根据每个分号拆分在现有表中创建新记录
  2. 用波浪号再次拆分每个标记,将第一部分放入一个字段中,将第二部分放入同一记录中的单独字段中(我不关心按管道拆分)

我不知道这是否可能,但我希望它是。我也希望只需要这样做一次,因为新系统会自动创建所有这些废话。我的 sproc-fu 在 MySQL 中非常糟糕,因此非常感谢任何帮助。

非常感谢!

【问题讨论】:

  • 如果涉及一些复杂的计算,您的原始计划就足够了

标签: mysql stored-procedures csv data-conversion


【解决方案1】:

这在 SQL 中似乎是一件非常糟糕的事情,但这是一个概念验证脚本。

如果您的输出看起来正确,请将 SELECT 替换为适当的 INSERT 语句,它应该会得到您想要的。

delimiter ;;

drop procedure if exists load_crazy_stuff;;

create procedure load_crazy_stuff(in s longtext)
begin
   declare pos       int;
   declare record    longtext;
   declare leftpart  int;
   declare rightpart longtext;
   set s = concat(s,';');
   while length(s)>0 DO
     set pos       = instr(s,';');
     set record    = left(s,pos-1);
     set s         = substr(s,pos+1);
     set pos       = instr(record,'~');
     set leftpart  = left(record,pos-1);
     set rightpart = substr(record,pos+1);
     select leftpart, rightpart;
   end while;
end;;

call load_crazy_stuff('3~S|Red|Top;1~S|Blue|Top;20~XL|Green|Left');;

【讨论】:

  • AMAZING... 好的,现在,为了进一步扩展这一步,我如何针对现有表运行它,其中“crazystuff”字符串位于多个记录的单个字段中?非常感谢
  • 您可以尝试连接所有数据并输入我的 load_crazy_stuff proc。应该这样做:调用 load_crazy_stuff((select group_concat(yourfield separator ';') from yourtable));
【解决方案2】:

不粗暴的做法是这样的:

load data infile '/tmp/your-data-file' into table yourtable fields terminated by '~' lines terminated by ';';

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-02
    • 2011-08-17
    • 2012-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多