【问题标题】:mySql Dynamic Pivot Query with over 3000 columns具有超过 3000 列的 mySql 动态数据透视查询
【发布时间】:2016-04-05 23:08:54
【问题描述】:

美好的一天, 我正在使用动态数据透视查询按月生成产品销售的交叉表。产品刚刚超过 3K,这意味着超过 3k 列。当我运行查询时,我得到一个错误。如果我将原始表中的行数限制在 1586 以下,它运行良好,输出为 16 col,包括“日期”字段。我无法弄清楚这一点,需要一些帮助!请看下面的代码和错误:

SET @sql = NULL;
SELECT
  GROUP_CONCAT(DISTINCT
    CONCAT(
      'max(case when PSHDSTK = ''',
      PSHDSTK,
      ''' then MthSales end) AS `',
      PSHDSTK,
      '`'
    )
  ) INTO @sql
FROM  salesbyrow;

SET @sql = CONCAT('SELECT thedate, ', @sql, ' 
                  FROM salesbyrow
                                    GROUP BY thedate');

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

我得到的错误是

[Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM salesbyrow
                                    GROUP BY thedate' at line 2

【问题讨论】:

  • 如果您有 3000 个 行 和与您有几个月一样多的 列,输出会不会更易于管理?
  • 这将是但不是为了我的目的。我需要它用于预测算法,它需要这种宽格式的数据。
  • 好的。您可能必须在应用程序代码中进行透视。即取3列:月+产品+金额;然后做枢轴/交叉表。

标签: mysql pivot-table


【解决方案1】:

“考虑我”将我引导至导致错误的原因,另一篇 Stackoverflow 帖子将我引导至解决方案。 stackoverflow.com/questions/2567000/…;。所以我增加了 SET SESSION group_concat_max_len 效果很好!无需额外编码。我刚刚加了。

SET SESSION group_concat_max_len = 250000;

到查询的顶部。效果很好!我是新来的,所以我无法投票“考虑我”,谁真正回答了导致问题的原因。

【讨论】:

    【解决方案2】:

    在一个小样本上对我来说一切似乎都很好。 您确定PSHDSTK 列中没有引号或可能破坏您的@sql 字符串的内容吗?

    在执行语句之前添加SELECT @sql 用于调试目的(如下所示)。

    另外,请注意字符串变量和 GROUP_CONCAT 的 MySQL 最大大小。但是,当您在执行查询之前查看查询时,这一点应该会变得清晰。

    如果 GROUP_CONCAT 最大长度是限制(默认为 1024),您应该更改其长度的临时设置(会话范围)。由以下人员完成:

    SET SESSION group_concat_max_len = 10000 -- to set it to 10 000
    

    示例:

    create table salesbyrow(thedate int, PSHDSTK varchar(2), MthSales int);
    insert into salesbyrow(thedate,PSHDSTK,MthSales) 
      values (1, 'a1', 6),(1, 'a2', 5), (1, 'a1', 3);
    

    您的代码:

    SET @sql = NULL;
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(
          'max(case when PSHDSTK = ''',
          PSHDSTK,
          ''' then MthSales end) AS `',
          PSHDSTK,
          '`'
        )
      ) INTO @sql
    FROM  salesbyrow;
    
    SET @sql = CONCAT('SELECT thedate, ', @sql, ' FROM salesbyrow GROUP BY thedate');
    

    检查@sql变量的完整性:

    select @sql;
    

    语句看起来像这样(正确):

    SELECT thedate, max(case when PSHDSTK = 'a1' then MthSales end) AS `a1`,max(case when PSHDSTK = 'a2' then MthSales end) AS `a2` FROM salesbyrow GROUP BY thedate
    

    现在正在执行...

    prepare stmt from @sql;
    execute stmt;
    

    结果:

    thedate     a1  a2
    1           6   5
    

    【讨论】:

    • 我认为你可能是对的。当我增加产品名称(列名)的大小时,我的 1586 阈值会下降。运行 length@sql) 给了我 1134 的限制。字符串变量的最大大小是多少?有关解决此问题的任何建议...前提是这是问题所在?
    • 在使用 GROUP_CONCAT 初始化后查看 @sql 变量。我相信你的专栏可能不适合那里。检查this answer on SO
    猜你喜欢
    • 2021-06-13
    • 1970-01-01
    • 2021-02-28
    • 1970-01-01
    相关资源
    最近更新 更多