今天一个同学遇到一个问题问我了,由于本人平时学习的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. [SHELL进阶] (转)最牛B的 Linux Shell 命令 (四)

    1.查看ASCII码表 man 7 ascii  很多人初学编程都会接触到ascii码的概念,有时候为了查某个符号的ascii值,可能还得翻箱倒柜找出当年的课本?Linux Manpage里面其实包含 ...

  2. XML解析器(转)

    常见C/C++ XML解析器有tinyxml.XERCES.squashxml.xmlite.pugxml.libxml等等,这些解析器有些是支持多语言的,有些只是单纯C/C++的.如果你是第一次接触 ...

  3. Error in notifier

    sudo apt-get install libnotify-bin or 在gulpfile.js第一行插入 process.env.DISABLE_NOTIFIER = true; 禁用notif ...

  4. Write Cache-friendly Code

    Computer Systems A Programmer's Perspective Second Edition In Section 6.2, we introduced the idea of ...

  5. 256 terabytes random-access memory

    Computer Systems A Programmer's Perspective Second Edition As we will discuss, the extension of IA32 ...

  6. 最有用的Linux命令行使用技巧集锦

    最近在Quora上看到一个问答题目,关于在高效率Linux用户节省时间Tips.将该题目的回答进行学习总结,加上自己的一些经验,记录如下,方便自己和大家参考. 下面介绍的都是一些命令行工具,这些工具在 ...

  7. 弹窗文件js+css

    // 每个弹窗的标识 var x =0; var idzt = new Array(); var Window = function(config){ //ID不重复 idzt[x] = " ...

  8. php+mysql实现事务回滚

    模拟条件:第一个表插入成功,但是第二个表插入失败,回滚.第一个表插入成功,第二个表插入成功,执行.第一个表插入失败,第二个表插入成功,回滚.第一个表插入失败,第二个表插入失败,回滚.以上情况都需要回滚 ...

  9. iOS自定义控件开发详解

    http://blog.csdn.net/zhangao0086/article/details/45622875

  10. 介绍UDF,以及完成大小写的转换

    一:概述 1.UDF 用户自定义函数,用java实现自定义的需求 2.UDF的类型 udf:一进一出 udaf:多进一出 udtf:一进多出 3.udf的实现步骤 继承UDF类 实现evaluate的 ...