Mysql动态行值作为列名

时间:2014-11-21 00:06:11

标签: mysql join dynamic row

最近我遇到了一个具有以下结构的项目

http://sqlfiddle.com/#!2/3a4cf/1

一切正常,我想我可以在PHP端对事情进行排序,但我的问题是,是否可以通过单个查询

number, name, age, email, gender
--------------------------------------------
123456, Test1, 24, test1@test.com, m
123457, Test2, 23, test2@test.com, f
123458, Test3, 22, test3@test.com, m
123459, Test4, 21, test4@test.com, f
123460, Test5, 25, test5@test.com, m

考虑列名是实际的     field.field_name

我尝试了多个左/右连接(尽可能多的字段数)但是这可以达到无限大声...即有100个字段将是200个连接以获得单行结果(仍然没有列名作为field_value)。

我看了下面的内容(可能重复):

mysql select dynamic row values as column names, another column as value

但对我说不多(不是在mysql :()中有经验。

如果可能的话,如果有人能指导我如何实现它,我将不胜感激。

提前致谢。

1 个答案:

答案 0 :(得分:1)

我想你想要这个查询

SELECT SQL_NO_CACHE
    n.number, n.name, 
MAX(CASE WHEN f1.field_name='age' THEN nf1.value END) as Age,
MAX(CASE WHEN f1.field_name='email' THEN nf1.value END) as Email,
MAX(CASE WHEN f1.field_name='gender' THEN nf1.value END) as Gender
FROM
    number AS n
        LEFT JOIN
    number_field AS nf1 ON n.id = nf1.number_id
        RIGHT JOIN
    field AS f1 ON f1.id = nf1.field_id
WHERE
    1 = 1
GROUP BY n.number,n.name
ORDER BY number

FIDDLE

动态

SET SESSION group_concat_max_len = 1000000;

SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
    CONCAT(
      'MAX(CASE WHEN f1.field_name= ''',
      f1.field_name,
      ''' THEN nf1.`value` END) AS ',
      f1.field_name
    )
   )INTO @sql
FROM  
    number_field AS nf1 
        RIGHT JOIN
    field AS f1 ON f1.id = nf1.field_id
ORDER BY f1.field_name;


SET @sql=CONCAT('SELECT n.number, n.name, ',@sql,' FROM
  number AS n
        LEFT JOIN
    number_field AS nf1 ON n.id = nf1.number_id
        RIGHT JOIN
    field AS f1 ON f1.id = nf1.field_id
GROUP BY n.number,n.name
ORDER BY number');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

FIDDLE