搜索

首页  >  问答  >  正文

MySQL透视表查询:利用动态列实现数据分析

<p>我正在使用以下表来存储产品数据:</p> <pre class="brush:php;toolbar:false;">mysql> SELECT * FROM product; +---------------+---------------+--------+ | id | name | description | stock | +---------------+---------------+--------+ | 1 | product1 | first product | 5 | | 2 | product2 | second product| 5 | +---------------+---------------+--------+ mysql> SELECT * FROM product_additional; +-----------------+------------+ | id | fieldname | fieldvalue | +-----------------+------------+ | 1 | size | S | | 1 | height | 103 | | 2 | size | L | | 2 | height | 13 | | 2 | color | black | +-----------------+------------+</pre> <p>使用以下查询从两个表中选择记录:</p> <pre class="brush:php;toolbar:false;">mysql> SELECT p.id , p.name , p.description ,MAX(IF(pa.fieldname = 'size', pa.fieldvalue, NULL)) as `size` ,MAX(IF(pa.fieldname = 'height', pa.fieldvalue, NULL)) as `height` ,MAX(IF(pa.fieldname = 'color', pa.fieldvalue, NULL)) as `color` FROM product p LEFT JOIN product_additional AS pa ON p.id = pa.id GROUP BY p.id +---------------+---------------+--------+---------+--------+ | id | name | description | size | height | color | +---------------+---------------+--------+---------+--------+ | 1 | product1 | first product | S | 103 | null | | 2 | product2 | second product| L | 13 | black | +---------------+---------------+--------+---------+--------+</pre> <p>一切都正常工作 :) </p> <p>因为我动态填充“additional”表,所以如果查询也是动态的就好了。这样我就不必每次输入新的字段名和字段值时都要更改查询。</p>
P粉101708623P粉101708623502 天前631

全部回复(2)我来回复

  • P粉046387133

    P粉0463871332023-08-23 11:13:47

    我有一种稍微不同的方法来完成这个任务,与接受的答案不同。这种方法可以避免使用默认情况下有1024个字符限制的GROUP_CONCAT,并且如果你有很多字段,它将无法工作,除非你改变限制。

    SET @sql = '';
    SELECT
        @sql := CONCAT(@sql,if(@sql='','',', '),temp.output)
    FROM
    (
        SELECT
          DISTINCT
            CONCAT(
             'MAX(IF(pa.fieldname = ''',
              fieldname,
              ''', pa.fieldvalue, NULL)) AS ',
              fieldname
            ) as output
        FROM
            product_additional
    ) as temp;
    
    SET @sql = CONCAT('SELECT p.id
                        , p.name
                        , p.description, ', @sql, ' 
                       FROM product p
                       LEFT JOIN product_additional AS pa 
                        ON p.id = pa.id
                       GROUP BY p.id, p.name, p.description');
    
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

    点击此处查看演示

    回复
    0
  • P粉768045522

    P粉7680455222023-08-23 00:34:41

    在MySQL中,唯一动态执行此操作的方法是使用预处理语句。以下是一篇关于它们的好文章:

    动态透视表(将行转换为列)

    你的代码将如下所示:

    SET @sql = NULL;
    SELECT
      GROUP_CONCAT(DISTINCT
        CONCAT(
          'MAX(IF(pa.fieldname = ''',
          fieldname,
          ''', pa.fieldvalue, NULL)) AS ',
          fieldname
        )
      ) INTO @sql
    FROM product_additional;
    
    SET @sql = CONCAT('SELECT p.id
                        , p.name
                        , p.description, ', @sql, ' 
                       FROM product p
                       LEFT JOIN product_additional AS pa 
                        ON p.id = pa.id
                       GROUP BY p.id, p.name, p.description');
    
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

    查看演示

    注意:GROUP_CONCAT函数的字符限制为1024个字符。请参阅参数group_concat_max_len

    回复
    0
  • 取消回复