将MySQL表重新格式化为网格

时间:2012-04-26 12:06:04

标签: mysql sql formatting

我有一张用于保存翻译的表格。它的布局如下:

id | iso | token | content
-----------------------------------------------
 1 | GB  | test1 | Test translation 1 (English)
 2 | GB  | test2 | Test translation 2 (English)
 3 | FR  | test1 | Test translation 1 (French)
 4 | FR  | test2 | Test translation 2 (French)

// etc

对于与表格一起使用的翻译管理工具,我需要将其输出为更像电子表格网格的内容:

 token          | GB                           | FR                          | (other languages) --> 
-------------------------------------------------------------------------------------------
 test1          | Test translation 1 (English) | Test translation 1 (French) |
 test2          | Test translation 1 (French)  | Test translation 2 (French) |
 (other tokens) |                              |                             |
       |        |                              |                             |
       |        |                              |                             |
       V        |                              |                             |

我认为这很容易,但结果却比我想象的要困难得多!

经过大量的搜索和挖掘后,我找到了group_concat,对于上面的特定情况,我可以开始工作并生成我正在寻找的输出:

select 
    token, 
    group_concat(if (iso = 'FR', content, NULL)) as 'FR',
    group_concat(if (iso = 'GB', content, NULL)) as 'GB'
from 
    translations
group by token;

然而,这当然是完全不灵活的。它只适用于我目前指定的两种语言。我添加新语言的那一刻我必须手动更新查询以将其考虑在内。

我需要上面查询的通用版本,它能够生成正确的表输出,而无需了解存储在源表中的数据。

有些消息来源声称你不能在MySQL中轻易做到这一点,但我确信它一定是可能的。毕竟,这是数据库首先存在的东西。

有没有办法做到这一点?如果是这样,怎么样?

2 个答案:

答案 0 :(得分:2)

您所寻求的通常称为动态交叉表,其中您可以动态确定输出中的列。从根本上说,关系数据库不是为了动态确定模式而设计的。实现所需目标的最佳方法是使用中间层组件构建类似于您显示的交叉表SQL语句,然后执行该语句。

答案 1 :(得分:1)

由于mysql的限制,我需要在查询端和1个查询中执行类似的操作,我会这样做:

<强>查询:

select token, group_concat(concat(iso,'|',content)) as contents
from translations
group by token

<强> “令牌”; “内容”

  

“test1”;“GB |测试翻译1(英文),FR |测试翻译1   (法语),IT |测试翻译1(意大利语)“”test2“;”GB |测试翻译   2(英语),FR |考试翻译2(法语),IT |考试翻译2   (意大利)“

当我绑定行时,我可以从逗号分割为行,并从管道中拆分为标题..