mysql行列转换方法总结
这是一道行转列并且构造交叉表的问题:
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行列转换方法总结的更多相关文章
- 【转载】mysql行列转换方法总结
[转载]mysql行列转换方法总结 [MySQL] 行列转换变化各种方法实现总结(行变列报表统计.列变行数据记录统计等) Mysql 列转行统计查询 .行转列统计查询 在某些数据库中有交叉表,但在My ...
- 【转】mysql行列转换方法总结
转:http://blog.chinaunix.net/uid-7692530-id-2567582.html 在某些数据库中有交叉表,但在MySQL中却没有这个功能,但网上看到有不少朋友想找出一个解 ...
- mysql 行列动态转换(列联表,交叉表)
mysql 行列动态转换(列联表,交叉表) (1)动态,适用于列不确定情况 create table table_name( id int primary key, col1 char(2), col ...
- MySQL行列转换
分类: Mysql/postgreSQL 在某些数据库中有交叉表,但在MySQL中却没有这个功能,但网上看到有不少朋友想找出一个解决方法,特发贴集思广义.http://topic.csdn.net/u ...
- 【学亮IT手记】MySql行列转换案例
create table score( name ), math int, english int ); ,); ,); ,); ,); SHOW tables; SELECT * from scor ...
- MySQL行列转换拼接
mysql> select TBL_ID,CREATE_TIME,LAST_ACCESS_TIME,TBL_NAME,TBL_TYPE from TBLS; +--------+-------- ...
- mysql行列互相转换
列转行: mysql> select * from test; +------+----------+-------+ | id | subject | score | +------+---- ...
- MySQL 行列相互转换
行列相互转换 /*创建表*/ CREATE TABLE ic ( NAME ), Product ), amount INT ); INSERT INTO ic VALUES (), (), (), ...
- Mysql 行列转换
一.第一种 原数据表 转换后 DROP TABLE IF EXISTS tempdynamic; CREATE TEMPORARY TABLE tempdynamic ( SELECT p.fsPay ...
随机推荐
- Web API框架学习——路由(一)
HttpConfiguration(ASP.NET Web API管道的配置是通过HttpConfiguration来完成) : 包括路由注册在内的对整个ASP.NET Web API管道的配置是通过 ...
- scanf函数之扫描集
前言 %[]是scanf函数不常用到的格式字符--扫描集(scanset),它的用法很简单,但却能巧妙地解决一些输入问题.(由于书籍里和网上对此格式字符的介绍很少且篇幅较小,本文可能会有些许错误,请读 ...
- HTML5微数据
本篇文章是一个纯搬运贴,原博主是在是做的太详细了 原贴地址:http://www.zhangxinxu.com/wordpress/2011/12/html5扩展-微数据-丰富网页摘要/ 一.微数据是 ...
- 解读web服务器与php的工作原理
最近决定重读php手册(好吧,其实之前也没怎么读,尴尬脸),既然是重读,那就从php的安装开始咯,然后被手册中出现的各种新词搞懵逼了,什么cgi.fastcgi.sapi.fpm,苍天啊,这些都是什么 ...
- windows和linux删除文件方法
Windows下bat文件内容如下:复制代码 代码如下: @echo offforfiles -p "D:\servers\apache2.2\logs" -s -m *.log ...
- ArcEngine保存栅格数据至rastercatalog
将栅格数据(IRasterDataset)直接保存到数据库中很常见,但是保存到栅格目录下就比较少见,好不容易才找到,在这里记录一下. public void saveRasterDs2Catalog( ...
- Java核心编程快速学习
Java核心编程部分的基础学习内容就不一一介绍了,本文的重点是JAVA中相对复杂的一些概念,主体内容如下图所示. 反射reflect是理解Java语言工作原理的基础,Java编译器首先需要将我们编写的 ...
- centos 6.5 搭建ftp服务器
linux下一般使用vsftpd作为ftp服务器. vsftpd是一款在Linux发行版中最受推崇的FTP服务器程序.特点是小巧轻快,安全易用. 下面是安装配置步骤: 1.安装vsftpd yum i ...
- Knockout Mvc Compoment FrameSet
Knockout Mvc Compoment FrameSet 框架文件结构 01- 网站(表现层),mvc主要作用视图展示. 02- 模型(Model),主要作用承载视图数据结构,网站前后台 ...
- [Linux] PHP程序员玩转Linux系列-nginx初学者引导
1.PHP程序员玩转Linux系列-怎么安装使用CentOS 2.PHP程序员玩转Linux系列-lnmp环境的搭建 3.PHP程序员玩转Linux系列-搭建FTP代码开发环境 4.PHP程序员玩转L ...