题:下表是一张商品出售统计表,写一段简单的sql查询,查询出每种商品类型每个月的出售总额,其中类型1为实体商品,类型2为虚拟商品。表名goods_count

id(自增id) sold_time(出售时间戳) amount(价格) goods_type(商品类型)
1 1425265920 23.50 2
2 1428203520 50.00 1
3 1430709120 100.00 1
4 1430795520 65.25 1
5 1431659520 255.20 2

要求打印如下结果:

月份 实体商品 虚拟商品
2015-03 0.00 23.50
2015-04 50.00 0.00
2015-05 162.25 255.20

模拟

  1. create DATABASE `test`;
  2. CREATE TABLE `goods_count`(
  3. `id` int AUTO_INCREMENT PRIMARY KEY ,
  4. `sold_time` int ,
  5. `amount` FLOAT,
  6. `goods_type` TINYINT
  7. );
  8. INSERT INTO `goods_count`(sold_time,amount,goods_type) VALUES(1425265920,23.50 ,2);
  9. INSERT INTO `goods_count`(sold_time,amount,goods_type) VALUES(1428203520,50.00 ,1);
  10. INSERT INTO `goods_count`(sold_time,amount,goods_type) VALUES(1430709120,100.00 ,1);
  11. INSERT INTO `goods_count`(sold_time,amount,goods_type) VALUES(1430795520,65.25 ,1);
  12. INSERT INTO `goods_count`(sold_time,amount,goods_type) VALUES(1431659520,255.20 ,2);

分析:

(1) 按月获取实体商品的出售总额

  1. SELECT ALL from_unixtime(sold_time, '%Y-%m') as m, IF(sum(amount) IS NULL , 0, round(sum(amount),2) ) as s
  2. FROM `goods_count`
  3. WHERE goods_type=1
  4. GROUP BY m

(2)按月获取虚拟商品的出售总额

  1. SELECT ALL from_unixtime(sold_time, '%Y-%m') as m, IF(sum(amount) IS NULL , 0, round(sum(amount),2) ) as s
  2. FROM `goods_count`
  3. WHERE goods_type=2
  4. GROUP BY m

(3)现在的问题是如何将两个表连接在一起?

  • 左连接
  1. SELECT ALL t1.m as '月份', IF(t1.s IS NULL , 0, t1.s) as '实体商品', IF(t2.s IS NULL , 0, t2.s) as '虚拟商品'
  2. FROM (
  3. SELECT ALL from_unixtime(sold_time, '%Y-%m') as m, round(sum(amount),2) as s
  4. FROM `goods_count`
  5. WHERE goods_type=1
  6. GROUP BY m
  7. ) as t1
  8. LEFT JOIN
  9. (
  10. SELECT ALL from_unixtime(sold_time, '%Y-%m') as m, round(sum(amount),2) as s
  11. FROM `goods_count`
  12. WHERE goods_type=2
  13. GROUP BY m
  14. ) as t2
  15. ON t1.m = t2.m;

  • 右连接:
  1. SELECT ALL t1.m as '月份', IF(t1.s IS NULL , 0, t1.s) as '实体商品', IF(t2.s IS NULL , 0, t2.s) as '虚拟商品'
  2. FROM (
  3. SELECT ALL from_unixtime(sold_time, '%Y-%m') as m, round(sum(amount),2) as s
  4. FROM `goods_count`
  5. WHERE goods_type=1
  6. GROUP BY m
  7. ) as t1
  8. RIGHT JOIN
  9. (
  10. SELECT ALL from_unixtime(sold_time, '%Y-%m') as m, round(sum(amount),2) as s
  11. FROM `goods_count`
  12. WHERE goods_type=2
  13. GROUP BY m
  14. ) as t2
  15. ON t1.m = t2.m;

  • 右连接优化:
  1. SELECT ALLIF( t1.m IS NULL, t2.m, t1.m) as '月份', IF(t1.s IS NULL , 0, t1.s) as '实体商品', IF(t2.s IS NULL , 0, t2.s) as '虚拟商品'
  2. FROM (
  3. SELECT ALL from_unixtime(sold_time, '%Y-%m') as m, round(sum(amount),2) as s
  4. FROM `goods_count`
  5. WHERE goods_type=1
  6. GROUP BY m
  7. ) as t1
  8. RIGHT JOIN
  9. (
  10. SELECT ALL from_unixtime(sold_time, '%Y-%m') as m, round(sum(amount),2) as s
  11. FROM `goods_count`
  12. WHERE goods_type=2
  13. GROUP BY m
  14. ) as t2
  15. ON t1.m = t2.m;

  • 思考

    此处的主要问题在于ON的连接条件,导致不能将未对应的月份显示出来。

最后只想到了一个最暴力的方法==》三表连接

  1. SELECT ALL a.m as '月份', IF(t1.s IS NULL , 0, t1.s) as '实体商品', IF(t2.s IS NULL , 0, t2.s) as '虚拟商品'
  2. FROM
  3. (select from_unixtime(sold_time, '%Y-%m') as m
  4. from goods_count
  5. group by m
  6. ) as a
  7. left join (
  8. SELECT ALL from_unixtime(sold_time, '%Y-%m') as m, round(sum(amount),2) as s
  9. FROM `goods_count`
  10. WHERE goods_type=1
  11. GROUP BY m
  12. ) as t1
  13. on a.m = t1.m
  14. left JOIN
  15. (
  16. SELECT ALL from_unixtime(sold_time, '%Y-%m') as m, round(sum(amount),2) as s
  17. FROM `goods_count`
  18. WHERE goods_type=2
  19. GROUP BY m
  20. ) as t2
  21. on a.m =t2.m;

【MySQL】一道MySQL综合题的更多相关文章

  1. MySQL查询笔试综合题练习

    题目要求: 在某个数据库下建表: create table stu( -> name char(3) not null default '', -> subject varchar(10) ...

  2. [WeChall] Training: MySQL I (MySQL, Exploit, Training)

    Training: MySQL I (MySQL, Exploit, Training) MySQL Authentication Bypass - The classic This one is t ...

  3. 涂抹mysql笔记-mysql性能调优和诊断

    <>关键性指标1.IOPS(Input/Output operations Per Second)每秒处理的I/O请求次数:需要说明的一点,通常提到磁盘读写能力,比如形容它每秒读300M写 ...

  4. MySQL: Table 'mysql.plugin' doesn't exist的解决

    安装解压版MySQL以后,不能启动,日志里面出现了这个错误: MySQL: Table 'mysql.plugin' doesn't exist 这是因为mysql服务启动时候找不到内置数据库&quo ...

  5. MySql 及 MySql WorkBench使用大全

    Mysql安装步骤 1. 下载MySQL Community Server 5.6.13 2. 解压MySQL压缩包 将以下载的MySQL压缩包解压到自定义目录下,我的解压目录是: "D:\ ...

  6. mac使用终端运行mysql,mysql终端,mysql mac,mysql目录,mysql路径

    首先去官网下载: http://www.mysql.com/downloads/ 我下载了5.6.11的dmg然后安装,安装完成之后..如果要用终端去玩SQL.那么一开始要输入很长的:/usr/loc ...

  7. yum安装mysql和mysql源,配置mysql

    申明,不要用root安装 1. 下载mysql的repo源 $ wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm ...

  8. MySQL服务 - MySQL列类型、SQL模式、数据字典

    MySQL列类型的作用: 列类型可以简单理解为用来对用户往列种存储数据时做某种范围"限定",它可以定义数据的有效值(字符.数字等).所能占据的最大存储空间.字符长度(定长或变长). ...

  9. OS 系统下安装MySql 配置MySql环境变量

    学习Hive需要,闲话不说 本文的内容: 下载Mysql for Mac 下载Mysql Workbench 安装 Mysql 和 Mysql Workbench 配置Mysql在OS 系统上的环境变 ...

  10. 详解 Spotlight on MySQL监控MySQL服务器

    前一章详解了Spotlight on Unix 监控Linux服务器 ,今天再来看看Spotlight on MySQL怎么监控MySQL服务器. 注:http://www.cnblogs.com/J ...

随机推荐

  1. monggo查询语法

    db.getCollection('vvt_user_reward').find({"description":"双节活动"})

  2. Django基础五之django模型层(二)多表操作

    一 创建模型 表和表之间的关系 一对一.多对一.多对多 ,用book表和publish表自己来想想关系,想想里面的操作,加外键约束和不加外键约束的区别,一对一的外键约束是在一对多的约束上加上唯一约束. ...

  3. css伪类和伪元素的区别,:before和::before的区别

    伪类用于选择DOM树之外的信息,或是不能用简单选择器进行表示的信息.前者包含那些匹配指定状态的元素,比如:visited,:active:后者包含那些满足一定逻辑条件的DOM树中的元素,比如:firs ...

  4. php 截取字符串指定长度

    ---恢复内容开始--- 一.直接取整,舍弃小数,保留整数:intval(): intval(9.21); /*结果是9*/ intval(9.89); /*结果是9*/ intval(string) ...

  5. c# axPageLayoutControl 加数据框

    private void axPageLayoutControl1_OnMouseDown(object sender, ESRI.ArcGIS.Controls.IPageLayoutControl ...

  6. 如何选择分布式事务形态(TCC,SAGA,2PC,基于消息最终一致性等等)

    各种形态的分布式事务 分布式事务有多种主流形态,包括: 基于消息实现的分布式事务 基于补偿实现的分布式事务 基于TCC实现的分布式事务 基于SAGA实现的分布式事务 基于2PC实现的分布式事务 这些形 ...

  7. Maven环境变量配置和在Eclipse中的配置

    1.Maven环境变量配置 M2_HOME :变量值为maven的安装目录 在path后添加%M2_HOME%\bin; 检查JDK,maven配置的cmd命令 echo %JAVA_HOME% ja ...

  8. Paxos可容错的一致性协议

    一致性问题要求多个process对一个值达成一致.基于消息传递的分布式系统中,在不考虑消息篡改等拜占庭错误的情况下,Paxos可以解决在进程退出,消息延迟,丢失,重复等异常发生的环境中对某个值达成一致 ...

  9. Jboss的jmx-console中查看内存和线程状态

    步骤: 1.假设jboss运行在 192.168.1.100:8080 地址和端口上. 2. 浏览器中访问http://192.168.1.100:8080/,然后选择jmx-console 3.选择 ...

  10. datediff

    DateDiff()是计算机函数. 中文名 日期比较函数 外文名 DateDiff() 作    用 得 出两个日期之间的间隔 用    途 返回两个日期之间的差值 允许数据类型 timeinterv ...