【问题标题】:Normalizing table data in mySQL procedurally在程序上规范化 mySQL 中的表数据
【发布时间】:2013-02-05 03:37:22
【问题描述】:

我有一个非规范化格式的大型数据集。以下是列名的示例:

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”)在子选择中使用字段名称和提取的索引#。

【问题讨论】:

    标签: mysql normalization


    【解决方案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 ...。这将给我一个运行语句来完成整个转换。

    【讨论】:

    • 有趣。因此,您建议使用 SQL 生成 SQL,然后将其复制并粘贴到新查询中以实际执行插入?
    • 不,他的查询结果将每行生成一条 SQL 语句,您可以遍历该结果集并在返回的行上使用 EXECUTE。请参阅我关于动态 SQL 的帖子。
    • @Tom Auger:是的,对于像一次性导入数据这样的管理功能,我将使用 SQL 和 information_schema 数据库来帮助我生成 SQL 语句。 (我宁愿这样做,也不愿做一堆乏味的编辑。)
    【解决方案2】:

    您正在寻找的是动态 SQL。您可以在此处执行可以以编程方式组合的 SQL 语句。只要您在存储过程中,就可以运行字符串中的任意 SQL 代码。见此链接:How To have Dynamic SQL in MySQL Stored Procedure

    基本上,您可以使用 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)
    

    【讨论】:

    • 这是非常有趣的东西,我以前从未尝试过。结合@spencer7593 的回复,这可能是我正在寻找的技巧。感谢您的链接。
    猜你喜欢
    • 2012-09-08
    • 2011-01-06
    • 2012-03-08
    • 2011-11-12
    • 1970-01-01
    • 2011-12-16
    • 2013-07-17
    • 1970-01-01
    相关资源
    最近更新 更多