我有一个非规范化格式的大型数据集。以下是列名称的示例:
foreign_key_ID,P1,P2,P3,P4,P5 ...... D1,D2,D3 ......等。
这些字段都包含相似类型的数据。
我需要将其规范化为现有的表结构:
insert into new_table (id, name, index)
select foreign_key_id, P1, 1
from denormalized_table;
但这意味着我需要为我的非规范化表中的每个字段运行单独的查询,只需更改一些内容:
insert into new_table (id, name, index)
select foreign_key_id, P2, 2
from denormalized_table;
考虑到我有多少这些领域,这变得乏味。
有没有办法可以将其自动化为单一操作?即:遍历字段(我不介意在某处创建一个符合条件的字段列表),拉出该字段名称的最后一位数字(即“P1”中的“1”和“P2”中的“2”)在子选择中使用字段名称和提取的索引#。
答案 0 :(得分:1)
基本上,您可以通过迭代一组列来使用mySQL语句构建字符串。您可以使用SHOW COLUMNS语法(请参阅http://dev.mysql.com/doc/refman/5.0/en/show-columns.html)返回一个集合,然后循环该结果集并构建您的动态查询字符串并以此方式执行。
SHOW COLUMNS FROM myTable WHERE Field NOT IN (pkey, otherFieldIDontWantToInclude)
答案 1 :(得分:1)
这是一个开始:
SELECT column_name, substr(column_name,2) AS `index`
FROM information_schema.columns
WHERE table_schema = 'mydatabasename'
AND table_name = 'denormalized_table'
AND column_name REGEXP '^[PD][0-9]+$'
ORDER BY column_name
您可以修改该语句中的选择列表,让MySQL为您生成语句:
SELECT CONCAT('INSERT INTO new_table (id, name, `index`) SELECT foreign_key_id, '
,column_name,', ',substr(column_name,2)
,' FROM denormalized_table ;') AS stmt
FROM information_schema.columns
WHERE table_schema = 'mydatabasename'
AND table_name = 'denormalized_table'
AND column_name REGEXP '^[PD][0-9]+$'
ORDER BY column_name
该输出将是一组您可以执行的MySQL INSERT语句。
如果要插入的数据的行数和总大小不是太大,您可以并且希望在“一个操作”中完成整个转换,那么您可以生成一个INSERT INTO ... SELECT语句,使用UNION ALL运算符。我会得到这样的大部分陈述:
SELECT CONCAT('UNION ALL SELECT foreign_key_id, '
,column_name,', ',substr(column_name,2)
,' FROM denormalized_table ') AS stmt
FROM information_schema.columns
WHERE table_schema = 'mydatabasename'
AND table_name = 'denormalized_table'
AND column_name REGEXP '^[PD][0-9]+$'
ORDER BY column_name
我会从中获取输出,并将第一个UNION ALL
替换为INSERT INTO ...
。这将给我一个单独的声明来完成整个转换。