`
jslfl
  • 浏览: 318640 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

mysql行列转换

阅读更多
网上查到,留作记录

数据样本:
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>

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

原文地址:http://blog.chinaunix.net/u3/90603/showart_2017912.html
分享到:
评论

相关推荐

    mysql 查询行列转换

    本篇文章将深入探讨“MySQL 查询行列转换”的概念及其实际应用,这在数据分析和报表展示时尤其重要。 行转列是数据处理中的常见需求,尤其是在数据透视或汇总分析时。在 MySQL 中,我们可以使用几种方法实现这一...

    mysql 行列动态转换的实现(列联表,交叉表)

    在MySQL中,行列转换是一种常见的数据处理需求,特别是在数据分析和报表生成时。列联表(Cross Tabulation)和交叉表(Pivot Table)是这种转换的两种术语,它们用于将行数据转换为列数据,或者反之。在描述的场景中...

    数据库实现行列转换(mysql示例)

    不过,MySQL提供了其他方法来实现行列转换。本文将通过两个示例讲解如何在MySQL中进行行列转换。 **示例一:使用CASE语句** 在MySQL中,可以利用`CASE`语句配合`SUM`或`GROUP BY`来实现行列转换。这种方法适用于...

    mysql动态行转列

    MySQL 动态行转列是指将数据库中的一行数据转换为多列数据的过程。在本示例中,我们将创建一个存储过程来实现动态行转列,用于从数据库中提取指定学生的成绩信息。 描述解释 MySQL 数据库中存在一个问题,即如何将...

    mysql行转列(将同一列下的不同内容的几行数据,转换成几列显示)、列转行、行列汇总、合并显示

    MySQL 行转列、列转行、行列汇总、合并显示 MySQL 行转列是一种常用的数据处理操作,用于将同一列下的不同内容的几行数据转换成几列显示。例如,我们有一个成绩表 tb_score,其中包含 userid、subject 和 score 三...

    sql 行专列 列转行 普通行列转换

    在SQL数据库操作中,行与列的转换是常见的数据处理需求。这通常涉及到将一列的数据拆分成多行,或者将多行数据合并为一列。这种操作在数据分析、报表生成以及数据清洗过程中非常常见。在SQL Server中,我们可以利用...

    MySql 列转行实例

    在MySQL数据库中,有时我们需要将数据表中的列转换为行,这一操作通常称为"行列转换"或"行列互换",在SQL语句中可以通过多种方法实现,如使用CASE语句、UNION ALL或者自连接等。在这个实例中,我们重点关注的是通过...

    mysql-行转列、列转行

    这种操作在SQL中通常被称为“透视”或“行列转换”。 标题“mysql-行转列、列转行”涉及到的是MySQL中的两种主要转换技巧: 1. **行转列(Pivot)**: 行转列通常用于将多行数据转换为单行的多个列。在MySQL中,...

    浅析SQL语句行列转换的两种方法 case…when与pivot函数的应用

    在SQL中,对数据进行行列转换是数据分析过程中常见的需求,特别是在报表展示或数据汇总时。本文将详细探讨两种实现这一转换的方法:`CASE...WHEN` 和 `PIVOT` 函数,通过具体的示例来解析它们的用法。 1. `CASE......

    Mysql 行转列 实现中派商家月额统计

    在数据分析和报表生成时,有时我们需要将数据从行格式转换为列格式,这在SQL中通常被称为“行列转换”。本篇内容主要围绕如何在MySQL中实现行转列,特别是针对商家月额统计这一具体场景进行探讨。 首先,我们要理解...

    mysql练习题

    MYSQL子查询、相关子查询、inner join、left|right join、cross join 、行列转换等高级查询练习题

    MYSQL培训经典教程(共两部分) 1/2

    MYSQL高级特性 81 4.1 集合函数 82 4.1.1 行列计数 82 4.1.2统计字段值的数目 82 4.1.3 计算字段的平均值 83 4.1.4 计算字段值的和 84 4.1.5 计算字段值的极值 84 4.1.6 总结 86 4.2 操作...

    mysql横向转纵向、纵向转横向排列的方法

    总结一下,MySQL中的行列转换主要依赖于`CASE`、`GROUP BY`、`UNION`等核心SQL语句。通过巧妙地组合运用这些语句,可以灵活地调整数据的布局,从而更好地满足数据分析和展示的需求。在进行转换时,务必注意数据的...

    sql表数据行列互换

    在数据库管理与数据分析领域,有时我们需要对表格中的数据进行特殊的处理,例如将行转换为列或将列转换为行,这样的操作被称为“行列互换”。这种需求通常出现在汇总报告、数据透视等场景下。本文将详细介绍如何在...

    MySQL学习之旅(一)查询一个字段中相同属性的最大值

    总结来说,本文介绍了如何在MySQL中查询一个字段中相同属性的最大值,提供了两种实用的方法,即通过行列转换和`MAX`函数,以及使用`GREATEST`函数。通过深入理解和实践这些技术,不仅可以提升SQL技能,也能在实际...

    sql.rar_SQL 脚本

    在SQL编程中,数据操作和分析常常涉及到对数据的行列转换。这是一项关键技能,尤其在处理复杂报表或数据分析任务时。"sql.rar_SQL 脚本"这个压缩包文件显然是一个关于SQL脚本的资源,其中包含了"sql.txt"这样一个...

    poi解析jsp上传的excel文件并导入mysql(支持xls和xlsx)优化版

    - 数据预处理可能包括数据类型转换、异常值处理等,以符合数据库字段的要求。 - 使用PreparedStatement批量插入数据,提高性能,避免SQL注入。 总的来说,这个项目实现了通过JSP接收用户上传的Excel文件,利用...

Global site tag (gtag.js) - Google Analytics