mysql 行转列

行转列

原文

在某些数据库中有交叉表,但在MySQL中却没有这个功能,但网上看到有不少朋友想找出一个解决方法,特发贴集思广义。
http://topic.csdn.net/u/20090530/23/0b782674-4b0b-4cf5-bc1a-e8914aaee5ab.html?96198
现整理解法如下:
数据样本:
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. 利用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>

  1. 利用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>
  2. 动态,适用于列不确定情况,
    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>
以上均由网友 liangCK , wwwwb , WWWWA , dap570 提供, 再次感谢他们的支持。
其实数据库中也可以用 CASE WHEN / DECODE 代替 IF

几个特殊 行数

SUM(IF())

select sum(if(qty > 0, qty, 0)) as total_qty from inventory_product group by product_id

意思是如果qty > 0, 将qty的值累加到total_qty, 否则将0累加到total_qty.

group by with rollup的用法

对已经查出来的数据,按照相应函数处理
原文

IFNULL

MYSQL IFNULL(expr1,expr2)
如果expr1不是NULL,IFNULL()返回expr1,否则它返回expr2。IFNULL()返回一个数字或字符串值,取决于它被使用的上下文环境。

时间: 2024-09-26 05:39:17

mysql 行转列的相关文章

mysql行转列统计查询的例子

我们在进行统计查询时,有时候需要将同一日期/位置等条件的不同信息进行行转列的统计,这时候会需要用到以下的方法进行统计,相当方便. 1. 表结构 > desc repair_record   ;                 +------------------------+---------------+------+-----+-------------------+-----------------------------+ | Field                  | Type

代码-MySql动态行转列,网上找的sql语句,需要再添加字段,求帮忙谢谢大家

问题描述 MySql动态行转列,网上找的sql语句,需要再添加字段,求帮忙谢谢大家 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))

MySQL存储过程中使用动态行转列_Mysql

本文介绍的实例成功的实现了动态行转列.下面我以一个简单的数据库为例子,说明一下. 数据表结构 这里我用一个比较简单的例子来说明,也是行转列的经典例子,就是学生的成绩 三张表:学生表.课程表.成绩表 学生表就简单一点,学生学号.学生姓名两个字段 CREATE TABLE `student` ( `stuid` VARCHAR(16) NOT NULL COMMENT '学号', `stunm` VARCHAR(20) NOT NULL COMMENT '学生姓名', PRIMARY KEY (`s

SQL行转列和列转行代码详解

行列互转,是一个经常遇到的需求.实现的方法,有case when方式和2005之后的内置pivot和unpivot方法来实现. 在读了技术内幕那一节后,虽说这些解决方案早就用过了,却没有系统性的认识和总结过.为了加深认识,再总结一次. 行列互转,可以分为静态互转,即事先就知道要处理多少行(列);动态互转,事先不知道处理多少行(列). --创建测试环境 USE tempdb; GO IF OBJECT_ID('dbo.Orders') IS NOT NULL DROP TABLE dbo.Orde

MySQL之伪列实现与实践

-------------------------------------------------------------------------------------------------正文-------------------------------------------------------------------------------------------------------------- 问题来源:基情 问题描述:看图说明一切 建表语句与模板数据: 点击(此处)折叠或

再说ASP输出N行N列表格

几乎在每个站点中我们都要使用程序来输出列表:新闻列表.产品列表等等,输出的方式也因内容的不同而不同,对于新闻列表,通常是一行一行的循环输出:对于产品列表,通常得一个单元格一个单元格的输出.下边我们就用ASP来输出一个五行四列的表格. 1.一行一行的输出 以下为引用的内容:<%Response.Write("<table border=""1"" width=""200"">")For i=

mssql 数据库表行转列,列转行终极方案

复制代码 代码如下: --行转列问题 --建立測試環境 Create Table TEST (DATES Varchar(6), EMPNO Varchar(5), STYPE Varchar(1), AMOUNT Int) --插入數據 Insert TEST Select '200605', '02436', 'A', 5 Union All Select '200605', '02436', 'B', 3 Union All Select '200605', '02436', 'C', 3

n 行n列的显示数据

数据|显示 <% rs.open sql,conn,1,1 i=1 do while not rs.eof if i mod 3 = 1 then response.write "<br/>" end if %> <td> <img hspace=1 src=""></td> <% if i mod 3 =0 then '每行三列 response.write "</tr>&qu

SQL Server中如何动态行转列

SQL Server 动态行转列(参数化表名.分组列.行转列字段.字段值) 一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 实现代码(SQL Codes) 方法一:使用拼接SQL,静态列字段: 方法二:使用拼接SQL,动态列字段: 方法三:使用PIVOT关系运算符,静态列字段: 方法四:使用PIVOT关系运算符,动态列字段: 扩展阅读一:参数化表名.分组列.行转列字段.字段值: 扩展阅读二:在前面的基础上加入条件过滤: 参考文献(Refe