最近在处理一些数据,要实现纵向数据横向显示的效果,在百度花费多个小时东征西伐南讨北战之后,终于找到一个概括的较为详尽的文章,特地转载过来以便更多的人解决相关问题,希望原作者不要介怀。

在某些数据库中有交叉表,但在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>

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>

以上均由网友  liangCK , wwwwb , WWWWA , dap570 提供, 再次感谢他们的支持。

其实数据库中也可以用 CASE WHEN / DECODE 代替 IF。

转载于:https://my.oschina.net/MiniBu/blog/83233

MySQL交叉表:纵向数据显示为横向。相关推荐

  1. mysql交叉表的构造知识_[数据库]MySQL交叉表

    [数据库]MySQL交叉表 0 2012-01-11 17:00:23 在某些数据库中有交叉表,但在MySQL中却没有这个功能,但网上看到有不少朋友想找出一个解决方法,特发贴集思广义. http:// ...

  2. MySQL交叉表:纵向数据显示为横向

    原文地址:https://my.oschina.net/MiniBu/blog/83233 最近在处理一些数据,要实现纵向数据横向显示的效果,在百度花费多个小时东征西伐南讨北战之后,终于找到一个概括的 ...

  3. mysql交叉表查询列转行_SQL 转置计算

    转置即旋转数据表的横纵方向,常用来改变数据布局,以便用新的角度观察.有些转置算法比较简单,比如行转列.列转行.双向转置:有些算法变化较多,比如动态转置.转置时跨行计算.关联转置等.这些转置算法对日常工 ...

  4. mysql 交叉表行转列_Oracle行转列、列转行的Sql语句总结

    多行转字符串 这个比较简单,用||或concat函数可以实现 SQL Code selectconcat(id,username)strfromapp_user selectid||usernames ...

  5. mysql 交叉表 存储过程_用于生成交叉表的存储过程的存储过程

    以前总是在网上搜一些交叉表生成的相关代码 但是使用起来总是很复杂 看看 刚出炉的东西对你来说是不是有所帮助 :_) 先看看下一个生成的存储过程 :SQLServer2000 Create Proced ...

  6. mysql 交叉表 存储过程_SQL存储过程实现SPSS交叉表(有图有真相)

    SP代码: /****** Object: StoredProcedure [dbo].[Pro_CrossTable] Script Date: 03/27/2014 20:46:38 ****** ...

  7. mysql 交叉表查询

    就不说了,直接上例子 a表 id  xue  fens  kem 1 1 20 语文 2 1 30  数学 3 2 40 语文 4 2 60 数学 5 3 20 语文 b表 bid    xinm 1 ...

  8. mysql交表_mysql 交叉表

    数据样本: create table tx( id int primary key, c1 char(2), c2 char(2), c3 int ); insert into tx values ( ...

  9. 生成交叉表的简单通用存储过程

    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_qry]') and OBJECTPROPERTY(id ...

最新文章

  1. 60 张图详解 98 个常见网络概念
  2. android studio 链接编辑,Android Studio怎么连接手机测试程序?
  3. Cocos Creator快速开通联网服务教程
  4. NYOJ_1013除法表达式
  5. oracle数据库存储过程中NO_DATA_FOUND不起作用解决
  6. 杀毒软件可以查杀所有计算机病毒吗,好的杀毒软件可以查杀任何病毒,对还是错?...
  7. tomcat-1-初识
  8. linux 系统管理员面试,经典linux系统工程师系统管理员面试题
  9. Excel表中的数据导入到数据库中
  10. NSOJ 一个人的旅行(图论)
  11. unity编辑器拓展(三) 预制体(Image)资源引用查找
  12. 微软更新iOS版Skype:新增@功能,一键召唤好友
  13. 基于单片机的智能数字电子秤设计
  14. 图像压缩工具ImageOptim介绍
  15. PNG-的IDAT解析
  16. 推荐一款语音识别软件
  17. 常用FPGA相关的网址资源
  18. android 开关机动画
  19. 基于python的Topsis(优劣解距离)算法的实现(附代码及举例说明)
  20. Python 身体质量指数BMI

热门文章

  1. unity 修改文件后缀_unity文件操作-添加。修改。删除
  2. 用python画卡通人物柒_追忆童年,教你用Python画出儿时卡通人物
  3. 更改计算机用户名 拒绝访问,电脑修改Administrator帐户属性提示拒绝访问的解决方法...
  4. Java - 中间件简介
  5. [ 2204听力 ] 二
  6. 如何在一个线程环境中使用一个线程非安全的java类
  7. 微信拟推出聊天记录付费云存储服务
  8. 学画画要从什么开始学?零基础怎么学好画画?
  9. C语言入门:利用冒泡排序算法实现将学生姓名按字典序排序
  10. 关于MCU中Timer/Counter接口及使用