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

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. python 接口自动化测试(三)

    1.WriteIni.py import ConfigParser cf = ConfigParser.ConfigParser() cf.add_section("PC_WSDL" ...

  2. jQuery中$.extend(true,object1, object2);深拷贝对象

    语法:jQuery.extend( [deep ], target, object1 [, objectN ] ) 深浅拷贝对应的参数就是[deep],是可选的,为true或false.默认情况是fa ...

  3. Java 中的锁——Lock接口

    Java SE5之后,并发包中新增了Lock接口(以及相关实现类)用来实现锁功能.虽然它少了(通过synchronized块或者方法所提供的)隐式获取释放锁的便捷性,但是却拥有了锁获取与释放的操作性. ...

  4. php函数的使用

    <?php header("Content-type:text/html; charset=utf-8"); //普通函数 echo "<br/>--- ...

  5. boost.asio源码阅读(1) - 从chat_server开始

    1. 关于示例代码 chat 先从简单的入手, 在如下路径:boost_1_63_0/libs/asio/example/cpp11/chat中找到chat_server.cpp 查看其成员, pri ...

  6. windows下的python flask环境搭建

    在Windows中搭建flask框架分为如下几步 1. 下载ez_setup.py文件,然后在cmd中执行 链接:http://pan.baidu.com/s/1qXOSeHu 密码:jkbw pyt ...

  7. MySQL1236错误的恢复

    从库出现问题 mysql> show slave status\G; *************************** . row *************************** ...

  8. Pycharm集成PyQt4并使用

  9. Python之xml文档及配置文件处理(ElementTree模块、ConfigParser模块)

    本节内容 前言 XML处理模块 ConfigParser/configparser模块 总结 一.前言 我们在<中我们描述了Python数据持久化的大体概念和基本处理方式,通过这些知识点我们已经 ...

  10. ajax ----进度条的原理

    一.进度条的原理 新知识点:Html5中FormData,xmlHttpRequest中的upload属性,progress事件监控 xmlHttpRequest中的upload属性,实现: < ...