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 ...
随机推荐
- (102, "Incorrect syntax near '-'.DB-Lib error message 102, severity 15:\nGen
python 调用MSSQL存储过程,运行时报错 sql="exec spname %s,%s"%(param1,param2) 这是错误的调用存储过程的语句,param1和par ...
- 用python抓取求职网站信息
本次抓取的是智联招聘网站搜索“数据分析师”之后的信息. python版本: python3.5. 我用的主要package是 Beautifulsoup + Requests+csv 另外,我将招聘内 ...
- SQL函数和SQL Server2008
1.绝对值 SQL:select abs(-1) value O:select abs(-1) value from dual 2.取整(大) S:select ceiling(-1.00 ...
- idea调试SpringMvc, 出现:java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener错误的解决办法
有时,使用idea开发SpringMvc发现调试时出现以下错误: 12-Mar-2017 12:08:02.345 严重 [RMI TCP Connection(2)-127.0.0.1] org.a ...
- web从入门开始(3)-----第一个网页
<meta>:是进行网页格式初始化的命令,确定网页使用的文本格式和编码格式 Background:中的路径,必须为相对路径 l HTML文本标记 <b>HTM文本</b ...
- .net Core 1.0.1 下的Web框架的的搭建过程step by step
环境:ubuntu+VScode 数据库:mysql ,ORM框架:chloe 官网 看完本篇文章你能学会 在Vscode下创建项目,一些基础的命令 ,以及得到一个配置文件的简单读取实例 1,在VS ...
- Nagios安装部署
p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; line-height: 150%; fon ...
- 关于ng路由的传参问题(传递一个,多个参数)
在ng的页面条转传参数的方法,ui-sref,$state Ui-sref:用于html页面进行单页面的跳转 $state:用于js代码中跳转 重点:明确传递方,接受方 [传递单个参数] 对于传递方: ...
- GPU加速有坑?
大多数人都知道有动画的地方可以使用GPU来加速页面渲染. 例如,做优化的时候,将使用left和top属性的动画修改成使用transform属性的CSS动画.或者听到别人教你使用transform:tr ...
- vue获取dom元素内容
通过ref来获取dom元素 在vue官网上对ref的解释 ref 被用来给元素或子组件注册引用信息.引用信息将会注册在父组件的 $refs 对象上.如果在普通的 DOM 元素上使用,引用指向的就是 D ...