有没有办法在不使用CASE的情况下将行转移到MySQL中的列?

时间:2010-11-02 15:05:44

标签: sql mysql pivot crosstab calculated-columns

有许多帖子可以将行转换为各种数据库的列。它们似乎分为两个阵营,使用case语句或使用数据库供应商的内置函数。我正在使用 MySQL ,并且在任何内置函数中都没有找到任何内容,这将允许我转向我想要转移到列中的任意未知数量的行值。如果我不提前知道这些值,我就无法构建在stackoverflow上频繁出现的CASE查询。我想知道MySQL中是否有类似于其他数据库中的东西,它被称为交叉表或枢轴:

-Postgresql:http://www.postgresql.org/docs/current/static/tablefunc.html
-Oracle:http://www.oracle-base.com/articles/11g/PivotAndUnpivotOperators_11gR1.php
-SQL Server:http://msdn.microsoft.com/en-us/library/ms177410.aspx

为了确保当我说将行数转换为列时我清楚我要求的是什么,我想要转换像这样的表

user_id键值
鲍勃头发棕色
短发 蓝眼睛
杰克的头发棕色
可靠的人 高度6'2"

进入这个:

user_id头发眼睛高度
鲍勃·布朗 蓝色
杰克·布朗 6'2"

我正在寻找 MySQL 中的解决方案,所以如果有任何特定的数据库是新的或者你想知道的,可以解决这个问题,我将不胜感激。

1 个答案:

答案 0 :(得分:2)

如果事先知道列名,Kangkan提供的链接将向您展示如何解决此问题。除了使用动态SQL构建语句之外,我们将采用相同的逻辑。每个字段有2个部分需要包含,select语句中的字段和适当的连接以获取值...所以我们需要在两个部分中构建语句

首先声明3个变量来构建这个...我将使用@ select,@ join和@sql这个例子。为变量赋予初始值

 set @select = 'select user_id,'
 set @join = 'from table t'

现在声明并加载一个带有table.key字段中不同值的游标。我将使用@field作为变量填充不同的table.key字段。然后循环遍历它构建两个变量:

 set @select = @select + ', ' + @field + '.value as '+@field+'
 set @join = @join + ' left join table ' + @field + 'on '+@field+'.key = t.key and and '+@field+'.user_id = t.user_id

(连接旨在使用@field中的值作为表的别名)

循环构建@select和@join的光标。在循环结束时:

set @sql = @select + @join + 'where clause if you want'
exec @sql

像这样构建的动态SQL可能是一个绝对痛苦的麻烦射击(并且正确)并打开安全问题......但这是我能看到这个完成的唯一方法。注意变量的大小限制....如果你有太多不同的Key,变量会变得太大。对不起我对这个伪问题不能更精确...你会发现在sql中构建动态sql很费劲。