今天一个同学遇到一个问题问我了,由于本人平时学习的mysql比较基础,确实没解决,后来google了一下,才知道是sql的一种技法【行列转换】,话不多说先上图:

想得到下面的结果:

+------+-------+-------+-------+-------+
| 年份 | 1月 | 2月 | 11月 | 12月 |
+------+-------+-------+-------+-------+
| 2014 | 0 | 0 | 20000 | 21000 |
| 2015 | 30000 | 60000 | 0 | 0 |
+------+-------+-------+-------+-------+

先上数据样本(数据表是随意建的,差不多就那个意思):

CREATE TABLE `order_sum` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`year` smallint(4) unsigned NOT NULL,
`month` tinyint(3) unsigned NOT NULL,
`money` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;

准备插入的数据:

INSERT INTO `order_sum` VALUES (1, 2014, 11, 20000);
INSERT INTO `order_sum` VALUES (2, 2014, 12, 21000);
INSERT INTO `order_sum` VALUES (3, 2015, 1, 30000);
INSERT INTO `order_sum` VALUES (4, 2015, 2, 60000);

插入后的数据结构:

mysql> select * from order_sum;
+----+------+-------+-------+
| id | year | month | money |
+----+------+-------+-------+
| 1 | 2014 | 11 | 20000 |
| 2 | 2014 | 12 | 21000 |
| 3 | 2015 | 1 | 30000 |
| 4 | 2015 | 2 | 60000 |
+----+------+-------+-------+
4 rows in set (0.00 sec)

利用sum(if())来生成列,将对应的数据填充到对应的列下面

SELECT
  YEAR AS '年份',
  sum(IF(MONTH = 1, money, '0')) AS '1月',
  sum(IF(MONTH = 2, money, '0')) AS '2月',
  sum(IF(MONTH = 11, money, '0')) AS '11月',
  sum(IF(MONTH = 12, money, '0')) AS '12月',
  sum(money) AS total
FROM
  order_sum
  GROUP BY YEAR

如果要计算出每个月的平均数已经汇总的平均数,则要使用子句

SELECT
  YEAR AS '年份',
  sum(IF(MONTH = 1, money, '0')) AS '1月',
  sum(IF(MONTH = 2, money, '0')) AS '2月',
  sum(IF(MONTH = 11, money, '0')) AS '11月',
  sum(IF(MONTH = 12, money, '0')) AS '12月',
  sum(money) AS total
FROM
  order_sum
  GROUP BY YEAR

UNION ALL

SELECT

  "总平均数",
  ROUND(AVG(1月),2) ,

  ROUND(AVG(2月),2),

  ROUND(AVG(11月),2),

  ROUND(AVG(12月),2),

  ROUND(AVG(total),2)
  FROM(
    SELECT

      YEAR AS "年份",
      sum(IF(MONTH = 1, money, '0')) AS '1月',
      sum(IF(MONTH = 2, money, '0')) AS '2月',
      sum(IF(MONTH = 11, money, '0')) AS '11月',
      sum(IF(MONTH = 12, money, '0')) AS '12月',
      sum(money) AS total
    FROM order_sum
    GROUP BY YEAR
  )tb2

这样就会得到如下的结果:

其中if可以用case when then else end来代替

sum(if(month=1,money,'0')) as '1月'

改成

max(case month when '1' then money else 0 end)  as '1月'

另外mysql行转列的函数:group_concat

mysql> select year,group_concat(money) from order_sum group by year;
+------+---------------------+
| year | group_concat(money) |
+------+---------------------+
| 2014 | 20000,21000 |
| 2015 | 30000,60000 |
+------+---------------------+

参考:http://blog.sina.com.cn/s/blog_4586764e0100lzmx.html

mysql:sql行列转换的更多相关文章

  1. SQL行列转换6种方法

    在进行报表开发时,很多时候会遇到行列转换操作,很对开发人员针对于SQL级别行列转换操作一直不甚理解,今天正好抽空对其进行了一些简单的总结.这里主要列举3种可以实现SQL行列转换的方法,包括通用SQL解 ...

  2. 数据透视表sql:用SQL行列转换实现数据透视的一些思考

    用SQL行列转换实现数据透视的一些思考 摘要:根据对报表开发过程中碰到的需要用SQL行列转换进行解决的一类查询统计问题的分析,逐步探索求解得到一种较通用的解决思路,并用函数进行实现.该解决思路及函数实 ...

  3. MySQL中行列转换的SQL技巧

    行列转换常见场景 由于很多业务表因为历史原因或者性能原因,都使用了违反第一范式的设计模式.即同一个列中存储了多个属性值(具体结构见下表). 这种模式下,应用常常需要将这个列依据分隔符进行分割,并得到列 ...

  4. Mysql实现行列转换

    前言: 最近又玩起了sql语句,想着想着便给自己出了一道题目:“行列转换”.起初瞎折腾了不少时间也上网参考了一些博文,不过大多数是采用oracle数据库当中的一些便捷函数进行处理,比如”pivot”. ...

  5. sql行列转换

    首先我们建立一张表,名为scoreInfo,各个字段的设计如下图,分别是name,course,score,表示姓名,成绩与分数,如图所示.

  6. SQL行列转换:报表_公司采购表_每个公司各采购了些什么产品

    有同学问了个比较典型行列转换的问题,想想,解答如下:数据库有一张表: 是个公司采购表,想转化成如下报表,显示每个公司各采购了些什么产品: 哪些公司采购哪些产品是不确定的,所以报表的列有哪几项是不确定的 ...

  7. 绝妙的SQL行列转换语句

      说明:普通行列转换(version 1.0)仅针对sql server 2000提供静态和动态写法,version 2.0增加sql server 2005的有关写法. 问题:假设有张学生成绩表( ...

  8. 经典SQL行列转换

    -- http://www.programbbs.com/doc/4885.htm /* 标题:普通行列转换(version 2.0) 说明:普通行列转换(version 1.0)仅针对sql ser ...

  9. SQL 行列转换简单示例

    SQLSERVER 2005 以后提供了新的方式进行行列转换,下面是一个实例供参考: if object_id('tb') is not null drop table tbTest go ),季度 ...

随机推荐

  1. Win10开始菜单打不开?两个办法可破

    很多人在安装Windows10后,都遇到过开始菜 单无法打开和Cortana框架无法输入文字的问题, 这种问题在系统更新后特别频繁.Windows会报错 为关键错误,并提示在下次登录会进行解决,同时要 ...

  2. 给Android程序员的六个建议

    给Android程序员的六个建议 分类: 安卓相关2015-07-14 23:58 177人阅读 评论(0) 收藏 举报 android程序员 如果你一年前写的代码 , 在现在看来你还感觉写的很不错 ...

  3. 【IOS笔记】Views

    Views Because view objects are the main way your application interacts with the user, they have many ...

  4. 解决ORA-00054资源正忙的问题

    有时候在drop表或者其他对象的时候,会遇到ORA-00054:资源正忙,要求指定NOWAIT(中文字符集)或者ORA-00054: resource busy and acquire with NO ...

  5. Nginx 日志文件切割

    Nginx 是一个非常轻量的 Web 服务器,体积小.性能高.速度快等诸多优点.但不足的是也存在缺点,比如其产生的访问日志文件一直就是一个,不会自动地进行切割,如果访问量很大的话,将 导致日志文件容量 ...

  6. PureBasic 打开一个一行有多个数据的文件并读取其中某个数据

    如果有一个文件如下: TITLE = "Water Wurface Elevation"VARIABLES = "X", "Y", &quo ...

  7. Bluetooth RFCOMM介绍

    目录 1. 介绍 2. 服务概述 2.1 RS-232控制信号 2.2 Null Modem Emulation 2.3 多串口仿真 3. 服务接口描述 4. RFCOMM帧类型 5. RFCOMM帧 ...

  8. nRF51822之app_button控制uart的开启和关闭

    为什么要使用app_button来控制uart的开启和关闭 还是先上datesheet中uart开启的时候需要HFCLK,需要消耗大量大电流.所以在我们需要的时候需要通过io来通知nrf51822开启 ...

  9. FW nexus docker

    原文地址: http://www.cnblogs.com/wzy5223/p/5410990.html Nexus 3.0 可以创建三种docker仓库: 1. docker (proxy)     ...

  10. Android模拟器disconnected问题

    具体原因不明,偶尔会出现 window -> Show Views -> device -> view menu -> Reset adb  一般可以解决该问题