2014-03-27 73 views
0

我所有的列标题带有前缀号,1_X,2_X,等等...这使得使用只是一个基本的select语句在整个带上使数据到IDL不可能表。我不知道,但我看到两种可能的方式:从MySQL的列标题删除字符在MySQL数据库中

1)把与列名别名表。我可以使用TRIM或SUBSTRING_INDEX删除/替换前两个字符吗?

2)创建一个使用的信息架构递归遍历并删除该列标题的前两个字符,并创建这些头一个新表并在复制数据的程序。

如果有间没有如此多的不同表格(全部使用1_X,2_X等),手动选择1_X AS X没有问题,但这不可行。能够在select语句的列标题中使用TRIM/SUBSTRING会很好。

谢谢。

回答

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 

或者,你甚至可以得到一个完整的SELECT语句,如果你是包裹表达GROUP_CONCAT(W HICH产生选择列表),在另一个CONCAT

事情是这样的:

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是没有必要的,只是在反引号包裹的列名就足够了您的应用。

+0

prepending也可以很好地工作,这看起来很有希望,我迫不及待地想要开展工作。我用来将CSV数据提供给mysql数据库的程序已经使用了这种格式多年,现在我有成千上万的具有前导数字的列,并且没有终点。我会仔细检查引入反引号。 – user3306708

+0

我试图自己弄清楚这一点,但我遇到了麻烦,因为我也想了解更多关于CONCAT的信息。这工作几乎完美,但我无法在单个表上运行此查询。 – user3306708

+0

您可以添加“'AND c.table_name ='mytablename''”。我不确定我是否清楚,这个查询不针对任何特定的表,它只是产生一个SQL语句,将从表中提取行。它产生的SELECT语句可以作为CREATE VIEW语句的一部分使用,但我没有(也没有)建议这样做,因为您不想将性能查杀视图引入到您的MySQL模式中。 – spencer7593

0

我觉得你可以按照选项2。但是这不会是快速的解决方案。

解决这个另一种方式可能是,

  1. 生成要更正表架构脚本。
  2. 在记事本++或支持用找到的正则表达式的任何编辑的脚本。
  3. 搜索和与替换[0-9] + _表达和更换空字符串。
  4. 使用此脚本创建新表并将数据复制到这些表中。

这听起来像一个手动的方法,但你会为所有的表都这样做一次。

+0

有可能创建重复(或甚至零长度)列名称与删除前导数字字符。 – spencer7593

+0

这将是伟大的,直接和容易,但我需要它在sql命令中工作,因为新的表正在定期创建与领先的数字(不经常,但足够)。如果我不在将来帮助,我需要它尽可能地自动化。 – user3306708

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;