MySQL或PHP将行转换为列

时间:2016-10-03 10:15:02

标签: php mysql laravel-5.2

我有这种表:

enter image description here

根据用户输入动态生成月份。这个月也可以重复。但是,我想将月值转换为具有值的值的列,但是当在mysql中动态地尝试它时,它不允许我,因为它只能返回不同的值。

我也尝试删除下面的代码,但它不起作用。有什么想法吗?

CREATE DEFINER=`root`@`localhost` PROCEDURE `test`()
BEGIN
SET group_concat_max_len=2048;
SET @sql = NULL;

SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'MAX(IF(month = ''',
      month,
      ''', amount, NULL)) AS ',
      month
    )
  ) INTO @sql
FROM tmp_results;

SET @sql = CONCAT('SELECT r.account, 
                           r.region, ', 
                           @sql, '
                   FROM tmp_results r
                   LEFT JOIN accounts AS a
                   on r.account_id = a.id
                   GROUP BY r.account');

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

尝试在laravel 5中使用该集合但仍然无效,如果你有php的答案,我也欢迎它。我已经敲了几天来解决这个问题。

1 个答案:

答案 0 :(得分:1)

如果您想要多年使用单独的列,则必须将年份(从列date计算得出)添加到动态sql代码中:

CREATE DEFINER=`root`@`localhost` PROCEDURE `test`()
BEGIN
  SET group_concat_max_len=2048;
  SET @sql = NULL;

  SELECT GROUP_CONCAT(DISTINCT CONCAT(
      'MAX(IF(month = ''',
      month,
      ''' and year(date) = ',
      year(date),
      ', amount, NULL)) AS `',
      month,
      '_',
      year(date),
      '`'
    )
    order by date
  ) INTO @sql
  FROM tmp_results;

  if coalesce(@sql,'') != '' then
    set @sql = concat(', ', @sql);
  end if; 

  SET @sql = CONCAT(
    'SELECT r.account, 
     r.region ',  
     coalesce(@sql,''),
    ' FROM tmp_results r
     LEFT JOIN accounts AS a
     on r.account_id = a.id
     GROUP BY r.account, r.region');

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

列将命名为January_2017,我添加了order by date,否则它们通常是无序的。

我添加了group by r.region,否则如果您的服务器上启用only_full_group_by(这是从MySQL 5.7开始的默认值),它将无效。

我为空表添加了一个测试(否则会导致错误)。如果您不需要它并仅将我的部分代码复制到您的代码中,请注意r.region SET @sql = CONCAT('SELECT r.account, r.region '与代码相比后丢失的逗号,您可能需要重新添加它。

由于每个月的代码长度约为80,因此您可能需要增加group_concat_max_len以适应最大可能的查询。