Возьмите многовимированную строку в MySQL и преобразуйте в несколько записей
-
11-10-2019 - |
Вопрос
Я преобразую старый набор данных в недавно структурированную базу данных. В настоящее время у них есть данные в этом формате:
[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
Я хочу взять эту строку в каждой записи и сделать следующую:
- Создайте новую запись в существующей таблице, основанной на каждом полуколоне
- Снова разделите каждый токен на тилде, положив первую часть в одно поле, а второе - в отдельное поле (мне не волнует расщеплять трубку) в той же записи
Я не знаю, возможно ли это, но я надеюсь, что это так. Я также надеюсь сделать это только один раз, так как новая система будет автоматически позаботиться о создании всего этого дерьма. Мой Sproc-Fu довольно ужасен в MySQL, поэтому любая помощь очень ценится.
Спасибо большое!
Решение
Это кажется довольно грубой задачей в SQL, но вот сценарий проверки концепции.
Если вывод выглядит подходящим для вас, замените выбор на соответствующий оператор вставки, и он должен получить вам то, что вы хотите.
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');;
Другие советы
Необочечный способ сделать это:
load data infile '/tmp/your-data-file' into table yourtable fields terminated by '~' lines terminated by ';';