MySQL从列标题中删除字符

时间:2014-03-27 21:51:21

标签: mysql sql rename idl

MySQL数据库中的所有列标题都以数字,1_X,2_X等为前缀...这使得只使用基本的select语句将数据带入IDL就无法引入整个表。我不确定,但我看到两种可能的方式:

1)带有列名别名的表格。我可以使用TRIM或SUBSTRING_INDEX来删除/替换前两个字符吗?

2)创建一个使用信息模式的例程,以递归方式遍历并删除列标题的前两个字符,并创建一个包含这些标题的新表并复制数据。

如果没有那么多不同的表(所有表都有1_X,2_X等等),那么手动选择1_X AS X就没有问题,但这是不可行的。能够在select语句中的列标题上使用TRIM / SUBSTRING会很棒。

感谢。

3 个答案:

答案 0 :(得分:0)

我认为您可以按照选项2.但这不是快速解决方案。

另一种解决方法可能是,

  
      
  1. 为要更正的表生成架构脚本。
  2.   
  3. 在notepad ++或任何支持使用正则表达式查找的编辑器中打开脚本。
  4.   
  5. 搜索并替换为[0-9] + _表达式和空字符串以进行替换。
  6.   
  7. 使用此脚本创建新表并将数据复制到其中。
  8.   

这可能听起来像是一种手动方法,但是你会对所有的桌子做一次。

答案 1 :(得分:0)

查看执行2个选择的策略,一个用于列名称,另一个用于具有列别名的数据。您可能需要恢复某些脚本语言(如PHP)以获取帮助。

首先,获取列名称:

show columns from tbl_client;
+-------------------------------+-----------------------------------+------+-----+---------------------+-----------------------------+
| Field                         | Type                              | Null | Key | Default             | Extra                       |
+-------------------------------+-----------------------------------+------+-----+---------------------+-----------------------------+
| 1_X                           | int(11)                           | NO   | PRI | NULL                | auto_increment              |

然后,遍历结果并创建列别名列表

然后创建新选择

SELECT 1_X as NEW_COLUMN_NAME_FOR_FIELD_1 FROM tbl_client;

答案 2 :(得分:0)

无法在SQL语句中使用函数来更改分配给要返回的列的标识符。在结果集中指定列标识符的SQL方法是使用expr AS alias方法。


您可以在标识符前加上另一个有效字符,而不是修剪前导数字字符。 (修剪前导字符似乎可能会导致另一个问题,重复和/或零长度列名称。)

您可以使用SQL语句为您生成SELECT列表。

(注意:GROUP_CONCAT函数受某些系统/会话变量的限制:group_concat_max_lenmax_allowed_packet,虽然更改全局max_allowed_packet,但调整这些变量很容易可能需要重新启动MySQL。)

要将它返回到所有一行上的SELECT列表(假设您不会超出GROUP_CONCAT限制),例如:

SELECT c.table_schema
     , c.table_name
     , GROUP_CONCAT(
          CONCAT('t.`',c.column_name,'` AS `x',c.column_name,'`')
          ORDER BY c.ordinal_position
       ) AS select_list_expr
  FROM information_schema.columns c
  FROM information_schema.columns c
 WHERE c.table_schema = 'mydatabase'
 GROUP BY c.table_schema, c.table_name

或者,如果您将GROUP_CONCAT表达式(生成选择列表)包装在另一个CONCAT

中,您甚至可以取回整个SELECT语句

这样的事情:

SELECT CONCAT('SELECT '
          , GROUP_CONCAT(
               <select_list_expr>
            )
          , ' FROM `',c.table_schema,'`.`',c.table_name,'` t;'
       ) AS stmt
  FROM information_schema.columns c
 WHERE c.table_schema = 'mydatabase'
 GROUP BY c.table_schema, c.table_name

您可以为<select_list_expr>使用更聪明的表达式,检查前导“数字”字符,并为只需要它的列分配别名,并保持其他列不变,但这又引入了返回重复列名的可能性。

也就是说,如果您在同一个表中已经有名为'1_X''x1_X'的列。但精心挑选的主角可以避免这个问题...

通过对前导数字字符进行条件测试,<select_list_expr>可能更聪明,如下所示:

SELECT CONCAT('SELECT '
          , GROUP_CONCAT(
               CASE
               WHEN c.column_name REGEXP '^[[:digit:]]'
               THEN CONCAT('t.`',c.column_name,'` AS `x',c.column_name,'`')
               ELSE CONCAT('t.`',c.column_name,'`')
               END
           )
          , ' FROM `',c.table_schema,'`.`',c.table_name,'` t;'
       ) AS stmt
  FROM information_schema.columns c
 WHERE c.table_schema = 'mydatabase'
 GROUP BY c.table_schema, c.table_name

同样,使用这种方法可能会生成“重复”列名。可以扩展条件测试“c.column_name REGEXP”以检查其他“无效”前导字符。


作为旁注,在某些时候,有人认为用主要数字字符命名列是一个“好主意”。仅仅因为某些事情被允许并不意味着这是一个好主意。


然后再说一遍,也许所有的rigamarole都没有必要,只需将列名包装在反引号中就足够了。