这是一道行转列并且构造交叉表的问题:

http://topic.csdn.net/u/20090530/23/0b782674-4b0b-4cf5-bc1a-e8914aaee5ab.html

数据样本:

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>

期望结果

+------+-----+-----+-----+-----+------+
|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   |
+------+-----+-----+-----+-----+------+

1. 利用SUM(IF()) 生成列 + WITH ROLLUP 生成汇总行,并利用 IFNULL将汇总行标题显示为
Total

mysql>

SELECT
IFNULL(c1,'total')
AS total,
SUM(IF(c2='B1',c3,0)) AS B1,
SUM(IF(c2='B2',c3,0)) AS
B2,
SUM(IF(c2='B3',c3,0)) AS B3,
SUM(IF(c2='B4',c3,0)) AS
B4,
SUM(IF(c2='total',c3,0)) AS total
FROM (
SELECT
c1,IFNULL(c2,'total') AS c2,SUM(c3) AS c3
FROM tx   GROUP BY c1,c2
WITH
ROLLUP  
HAVING c1 IS NOT NULL
) AS A
GROUP BY c1
WITH
ROLLUP;

+-------+------+------+------+------+-------+
| 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, 1 warning (0.00 sec)

2. 利用SUM(IF()) 生成列 + UNION 生成汇总行,并利用 IFNULL将汇总行标题显示为
Total

mysql>

select
c1,
sum(if(c2='B1',C3,0)) AS B1,
sum(if(c2='B2',C3,0)) AS
B2,
sum(if(c2='B3',C3,0)) AS B3,
sum(if(c2='B4',C3,0)) AS B4,SUM(C3) AS
TOTAL
from tx
group by C1
UNION
SELECT 'TOTAL',sum(if(c2='B1',C3,0))
AS B1,
sum(if(c2='B2',C3,0)) AS B2,
sum(if(c2='B3',C3,0)) AS
B3,
sum(if(c2='B4',C3,0)) AS B4,SUM(C3) FROM TX;

+-------+------+------+------+------+-------+
|
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
|
+-------+------+------+------+------+-------+
5 rows in set (0.00
sec)

mysql>

3.  利用SUM(IF()) 生成列,直接生成结果不再利用子查询
mysql>

select
ifnull(c1,'total'),
sum(if(c2='B1',C3,0))
AS B1,
sum(if(c2='B2',C3,0)) AS B2,
sum(if(c2='B3',C3,0)) AS
B3,
sum(if(c2='B4',C3,0)) AS B4,SUM(C3) AS TOTAL
from tx
group by C1
with rollup ;

+--------------------+------+------+------+------+-------+
|
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)

mysql>

4. 动态,适用于列不确定情况,

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)

mysql>

其实数据库中也可以用 CASE
WHEN / DECODE 代替 IF

sum(if(c2='B1',C3,0))
AS B1

可改写为

sum(case
c2 when 'B1'
then C3 else 0 end) AS B1

mysql行列转换方法总结的更多相关文章

  1. 【转载】mysql行列转换方法总结

    [转载]mysql行列转换方法总结 [MySQL] 行列转换变化各种方法实现总结(行变列报表统计.列变行数据记录统计等) Mysql 列转行统计查询 .行转列统计查询 在某些数据库中有交叉表,但在My ...

  2. 【转】mysql行列转换方法总结

    转:http://blog.chinaunix.net/uid-7692530-id-2567582.html 在某些数据库中有交叉表,但在MySQL中却没有这个功能,但网上看到有不少朋友想找出一个解 ...

  3. mysql 行列动态转换(列联表,交叉表)

    mysql 行列动态转换(列联表,交叉表) (1)动态,适用于列不确定情况 create table table_name( id int primary key, col1 char(2), col ...

  4. MySQL行列转换

    分类: Mysql/postgreSQL 在某些数据库中有交叉表,但在MySQL中却没有这个功能,但网上看到有不少朋友想找出一个解决方法,特发贴集思广义.http://topic.csdn.net/u ...

  5. 【学亮IT手记】MySql行列转换案例

    create table score( name ), math int, english int ); ,); ,); ,); ,); SHOW tables; SELECT * from scor ...

  6. MySQL行列转换拼接

    mysql> select TBL_ID,CREATE_TIME,LAST_ACCESS_TIME,TBL_NAME,TBL_TYPE from TBLS; +--------+-------- ...

  7. mysql行列互相转换

    列转行: mysql> select * from test; +------+----------+-------+ | id | subject | score | +------+---- ...

  8. MySQL 行列相互转换

    行列相互转换 /*创建表*/ CREATE TABLE ic ( NAME ), Product ), amount INT ); INSERT INTO ic VALUES (), (), (), ...

  9. Mysql 行列转换

    一.第一种 原数据表 转换后 DROP TABLE IF EXISTS tempdynamic; CREATE TEMPORARY TABLE tempdynamic ( SELECT p.fsPay ...

随机推荐

  1. 列表总结Canvas和SVG的区别

    参考链接: 菜鸟教程 HTML5 内联SVG 经典面试题(讨论canvas与svg的区别) Canvas | SVG ---|--- 通过 JavaScript 来绘制 2D 图形|是一种使用 XML ...

  2. JavaWeb之Listener监听器

    监听在Java体系中运用的很广泛,在安卓开发.JavaWeb开发中到处存在,在其他语言也有类似的,如果有了解过设计模式那很容易理解实现的原理.不过对于开发者来说,使用观察者模式只需实现相应的接口就好, ...

  3. 设置border属性变化不同形状:三角形、圆形、弧形 2017-03-20

    一.通过设置边框----正方形.三角形 <style> .c{ height: 0px; width: 0px; border-top: 50px solid red; border-ri ...

  4. 【SCOI2008】着色方案

    题目: http://oj.changjun.com.cn/problem/detail/pid/2027 pre.cjk { font-family: "Droid Sans Fallba ...

  5. JS 拖动DIV 需要JQUERY 支持

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. CUDA随机数生成库curand——deviceAPI

    原创作品,如要转载请注明出处:http://www.cnblogs.com/shrimp-can/p/6590152.html 最近要在device函数中使用curand库生成随机数,查找了下资料,除 ...

  7. 解决codeblock不能运行的问题

    codeblock 编译失败 软件 IDE codeblock这软件的确不错,但是除此安装使用就会不小心入坑.你是不是满心欢喜的下载好codeblock,敲入代码,点击运行的时候却总是没反应呢? 如果 ...

  8. 在React中使用CSS Modules设置样式

    最近,一直在看React...那真的是一个一直在学的过程啊,从配置环境webpack,到基础知识jsx,babel,es6,没有一个不是之前没有接触的.其实,我内心是兴奋的啊,毕竟,活着就是要接触一些 ...

  9. 大数据时代日志分析平台ELK的搭建

    A,首先说说ELK是啥,  ELK是ElasticSearch . Logstash 和 Kiabana 三个开源工具组成.Logstash是数据源,ElasticSearch是分析数据的,Kiaba ...

  10. XML和JSON两种数据交换格式的比较

    在web开发领域,主要的数据交换格式有XML和JSON,对于在 Ajax开发中,是选择XML还是JSON,一直存在着争议,个人还是比较倾向于JSON的.一般都输出Json不输出xml,原因就是因为 x ...