数据样本:
create table tx( 
 id int primary key, 
 c1 char(2), 
 c2 char(2), 
 c3 int 
);
insert into tx values 
(1 ,'A1','B1',9), 
(2 ,'A2','B1',7), 
(3 ,'A3','B1',4), 
(4 ,'A4','B1',2), 
(5 ,'A1','B2',2), 
(6 ,'A2','B2',9), 
(7 ,'A3','B2',8), 
(8 ,'A4','B2',5), 
(9 ,'A1','B3',1), 
(10 ,'A2','B3',8), 
(11 ,'A3','B3',8), 
(12 ,'A4','B3',6), 
(13 ,'A1','B4',8), 
(14 ,'A2','B4',2), 
(15 ,'A3','B4',6), 
(16 ,'A4','B4',9), 
(17 ,'A1','B4',3), 
(18 ,'A2','B4',5), 
(19 ,'A3','B4',2), 
(20 ,'A4','B4',5);
 
mysql> select * from tx;
+----+------+------+------+
| id | c1   | c2   | c3   |
+----+------+------+------+
|  1 | A1   | B1   |    9 |
|  2 | A2   | B1   |    7 |
|  3 | A3   | B1   |    4 |
|  4 | A4   | B1   |    2 |
|  5 | A1   | B2   |    2 |
|  6 | A2   | B2   |    9 |
|  7 | A3   | B2   |    8 |
|  8 | A4   | B2   |    5 |
|  9 | A1   | B3   |    1 |
| 10 | A2   | B3   |    8 |
| 11 | A3   | B3   |    8 |
| 12 | A4   | B3   |    6 |
| 13 | A1   | B4   |    8 |
| 14 | A2   | B4   |    2 |
| 15 | A3   | B4   |    6 |
| 16 | A4   | B4   |    9 |
| 17 | A1   | B4   |    3 |
| 18 | A2   | B4   |    5 |
| 19 | A3   | B4   |    2 |
| 20 | A4   | B4   |    5 |
+----+------+------+------+
20 rows in set (0.00 sec)
mysql>
期望结果
+------+-----+-----+-----+-----+------+
|C1    |B1   |B2   |B3   |B4   |Total |
+------+-----+-----+-----+-----+------+
|A1    |9    |2    |1    |11   |23    |
|A2    |7    |9    |8    |7    |31    |
|A3    |4    |8    |8    |8    |28    |
|A4    |2    |5    |6    |14   |27    |
|Total |22   |24   |23   |40   |109   |
+------+-----+-----+-----+-----+------+

解决方案 »

  1.   

    动态,适用于列不确定情况,
    mysql> SET @EE=''; 
    mysql> SELECT @EE:=CONCAT(@EE,'SUM(IF(C2=\'',C2,'\'',',C3,0)) AS ',C2,',') FROM (SELECT DISTINCT C2 FROM TX) A;
     
    mysql> SET @QQ=CONCAT('SELECT ifnull(c1,\'total\'),',LEFT(@EE,LENGTH(@EE)-1),' ,SUM(C3) AS TOTAL FROM TX GROUP BY C1 WITH ROLLUP');
    Query OK, 0 rows affected (0.00 sec)
    mysql> PREPARE stmt2 FROM @QQ;
    Query OK, 0 rows affected (0.00 sec)
    Statement prepared
    mysql> EXECUTE stmt2;
    +--------------------+------+------+------+------+-------+
    | ifnull(c1,'total') | B1   | B2   | B3   | B4   | TOTAL |
    +--------------------+------+------+------+------+-------+
    | A1                 |    9 |    2 |    1 |   11 |    23 |
    | A2                 |    7 |    9 |    8 |    7 |    31 |
    | A3                 |    4 |    8 |    8 |    8 |    28 |
    | A4                 |    2 |    5 |    6 |   14 |    27 |
    | total              |   22 |   24 |   23 |   40 |   109 |
    +--------------------+------+------+------+------+-------+
    5 rows in set (0.00 sec)
      

  2.   

    建议体会这句返回的结果是什么样。
    SELECT @EE:=CONCAT(@EE,'SUM(IF(C2=\'',C2,'\'',',C3,0)) AS ',C2,',') FROM (SELECT DISTINCT C2 FROM TX) A;
      

  3.   

    SELECT DISTINCT C2 FROM TX这个是把c2这一列去重,把最后输出的列分别显示出来。
    但是CONCAT(@EE,'SUM(IF(C2=\'',C2,'\'',',C3,0)) AS ',C2,',') ,一直没看懂,这种写法。然后这个结果是:没看懂,为啥会输出这样 的结果来。
      

  4.   

    SELECT DISTINCT C2 FROM TX这个是把c2这一列去重,把最后输出的列分别显示出来。
    但是CONCAT(@EE,'SUM(IF(C2=\'',C2,'\'',',C3,0)) AS ',C2,',') ,一直没看懂,这种写法。然后这个结果是:没看懂,为啥会输出这样 的结果来。
     这是一种特殊的写法,在sql server也有完全类似的用法。就是实现 字符串的累加,类似于 变量= 变量 + 字符串,每次都会把TX表中的 C2列的值取一个,然后累加到 变量中,然后再取出下一个 C2列的值,再累加到 变量中,类似一个 for循环。