项目中的统计报表作的很多,需求中有按周、月统计数据的。查看了Mysql的API,发现Date_format是格式化日期的,看了Date_format()的具体说明后就用这个函数按周统计,sql大致如下:

selectDATE_FORMAT(check_date ,'%X-%V')dates,avg(weight)/10000weight from ho_body where user_id=295

andweight >0 and check_datebetween '2009-02-24' and '2010-02-24' group by dates

------------------------------------------------------------------------------------------------------

查出的结果为:

dates weight

2009-30 80.9

2009-31 80.425

2009-32 80.76666667

2009-33 80.75384615

2009-34 80.8

2009-35 79.88

2009-36 80.06

2009-37 79.875

2009-3879.075

2009-39 79.26666667

2009-40 79.16666667

2009-41 78.875

2009-42 78.33333333

2009-43 78.77272727

2009-44 77.625

2009-45 77.825

2009-46 77.575

2009-47 77.45

2009-48 81.25

2009-49 76.5

2009-50 77.83333333

2009-52 79.8

2010-02 79.2

%X

年,其中的星期日是周的第一天,4 位,与 %V 使用

%x

年,其中的星期一是周的第一天,4 位,与 %v 使用

%Y

年,4位

%y

年,2位

难道%X只能与%V一起用表示年-周,并且周日为一周开始,

%x与%v一起用,表示年-周,周一为一周开始?

再看到前面的

%V

周(01-53)星期日是一周的第一天,与%X使用

%v

周(01-53)星期一是一周的第一天,与%x使用

看来是这个意思了,我之前怎么就没有注意到这个特别之处呢?可能是当时作完以周统计,然后再写月统计时,一看m表示月,数值,就直接把Date_format('%X-%V')改为Date_format('%X-%m')了。再加上%Y年,4位,%m月,没有具体说明,所以一直没有发现,并且用%X-%m按月统计,测试了许多数据,发现年-月,数值全是正确的。结果在跨年的情况下有问题了。。。一般情况下我是会考虑跨年的情况的,比如在求一个日期属于这一年的第几周,在这个问题上,我测试2009-12-31,2010-01-01属于哪一周,2010-01-03是哪一周,发现之前的方法有bug,后来作了修正才正确。而这是用mysql函数统计,测试一些数据没问题就觉得ok了,根本没有想到这样写在跨年时有问题了。。。。

为了将这个问题彻底整理清楚,下面是我找到的详细解读:

Date_format可以使用的格式有:

格式

描述

%a

缩写星期名

%b

缩写月名

%c

月,数值

%D

带有英文前缀的月中的天

%d

月的天,数值(00-31)

%e

月的天,数值(0-31)

%f

微妙

%H

小时(00-23)

%h

小时(01-12)

%I

小时(01-12)

%i

分钟,数值(00-59)

%j

年的天(001-366)

%k

小时(0-23)

%l

小时(1-12)

%M

月名

%m

月,数值(00-12)

%p

AM或PM

%r

时间,12-小时(hh:mm:ss AM或PM)

%S

秒(00-59)

%s

秒(00-59)

%T

时间, 24-小时(hh:mm:ss)

%U

周(00-53)星期日是一周的第一天

%u

周(00-53)星期一是一周的第一天

%V

周(01-53)星期日是一周的第一天,与%X使用

%v

周(01-53)星期一是一周的第一天,与%x使用

%W

星期名

%w

周的天(0=星期日, 6=星期六)

%X

年,其中的星期日是周的第一天,4位,与%V使用

%x

年,其中的星期一是周的第一天,4位,与%v使用

%Y

年,4位

%y

年,2位

Mysql中还有另外几种返回日期的函数,如:

SELECT EXTRACT(YEAR_MONTH FROMdatecolum)返回格式如200902

EXTRACT()函数用于返回日期/时间的单独部分,比如年、月、日、小时、分钟等等。

语法

EXTRACT(unit FROM date)

date参数是合法的日期表达式。unit参数可以是下列的值:

Unit值

MICROSECOND

SECOND

MINUTE

HOUR

DAY

WEEK

MONTH

QUARTER

YEAR

SECOND_MICROSECOND

MINUTE_MICROSECOND

MINUTE_SECOND

HOUR_MICROSECOND

HOUR_SECOND

HOUR_MINUTE

DAY_MICROSECOND

DAY_SECOND

DAY_MINUTE

DAY_HOUR

YEAR_MONTH

Unit值

MICROSECOND

SECOND

MINUTE

HOUR

DAY

WEEK

MONTH

QUARTER

YEAR

SECOND_MICROSECOND

MINUTE_MICROSECOND

MINUTE_SECOND

HOUR_MICROSECOND

HOUR_SECOND

HOUR_MINUTE

DAY_MICROSECOND

DAY_SECOND

DAY_MINUTE

DAY_HOUR

YEAR_MONTH

检查了一下,大致没有问题,然后又开始寻找如何按月统计,然后就看Date_format的语法,

%m表示数值,%M表示名称,看后很兴奋的试一下:

select distinct DATE_FORMAT(check_date ,'%X-%m') c1,avg(weight)/10000 wei from ho_body where user_id=295

and weight >0 and check_date between '2009-02-24' and '2009-10-31' group by c1

——————————————————————————————————————

c1 wei

2009-08 80.66388889

2009-09 79.70555556

2009-10 78.83714286

然后测试这样计算的结果是否正确,经过测试,果然是没问题的,很有成就感。然后就用这个方法统计,拿取数据,然后将这些统计的结果作为数据集,用JfreeChart画图。后期测试时,发现画的统计图横轴日期有问题,时间范围为2009-02-24~2010-02-24时,图片中竟然多出一个2009年1月,并且在最右侧。我确信我是经过排序的,不可能2009年1月会在最右侧,之后再调试,竟然发现数据库中根本就没有09年1月的数据,更直观的错误是,以between '2009-02-24' and '2009-10-31' 条件,根本不可能出现2009-01。

然后将错误原因定位在sql语句上,执行这个语句,果然,原因就在这里:

select distinct DATE_FORMAT(check_date ,'%X-%m') c1,avg(weight)/10000 wei from ho_body where user_id=295

and weight >0 and check_date between '2009-02-24' and '2010-02-24' group by c1

————————————————————————————————————————

c1 wei

2009-01 79.8

2009-08 80.66388889

2009-09 79.70555556

2009-10 78.83714286

2009-11 77.64285714

2009-12 78.75

2010-01 79.2

这个09年1月到底是哪里出来的,我先确定2009年1月是否有数据,结果测试最早的数据为2009-08-01,并没有1月的任何数据。既然最早的数据是8月,那么就测试这个多出来的2009-01是从哪里冒出来的。

我就用最笨的方法测试:

select distinct DATE_FORMAT(check_date ,'%X-%m')c1 from ho_body where user_id=295 and check_date between '2009-08-01' and '2009-08-31' order by c1

————————————————————————————————————————

c1

2009-08

问题不在8月。继续测试:

select distinct DATE_FORMAT(check_date ,'%X-%m')c1 from ho_body where user_id=295 and check_date between '2009-9-01' and '2009-09-30' order by c1

——————————————————————————————————————

c1

2009-09

……

……

直到2010年时,

select distinct DATE_FORMAT(check_date ,'%X-%m')c1 from ho_body where user_id=295 and check_date between '2010-01-01' and '2010-01-31' order by c1

————————————————————————————————————————

c1

2009-01

2010-01

问题就是2010年1月,并且,如果将条件改为between '2010-01-02' and '2010-01-31' 则不会多出2009-01。难道是Date_format函数有bug,在跨年时没有考虑正确,将2010年1月1日归为2009年的1月中?当然我也有怀疑过是我的sql语句有问题,仔细再看了看Date_format()的语法,

%X表示年,周日为一周第一天

%x表示年,周一为一周第一天

%M表示月,名称

%m表示月,数值,01形式

%V表示周,周日为第一天

%v表示周,周一为第一天

...........

看来看去,感觉没什么错误呀,感觉自己对这个研究的够清楚明白了,一定没有问题的。

mysql有bug的想法我坚持了一下午,在我和一个同事说这个bug的时候,老大听到了,问我具体怎么回事,我就给她讲解,特别奇怪的地方在于数据库根本没有09年1月的数据,用mysql中的Date_format的按月统计函数时,在跨年时有问题。老大也觉得这个问题不可思议,这时那个同事说,你怎么用X表示年呀,一般不都是有Y表示年吗?我还反驳说,这个没区别的呀,都是一样的,表示年嘛,4位的。。。。

分享到:

2011-02-11 13:47

浏览 1633

分类:数据库

评论

mysql每个月数据按天行转列_Mysql 中使用DATE_FORMAT函数按月、周统计数据相关推荐

  1. excel中使用CORREL函数计算两个时间序列数据列之间的滚动相关性(Rolling correlations)、例如,计算两种商品销售额之间的3个月的滚动相关性

    excel中使用CORREL函数计算两个时间序列数据列之间的滚动相关性(Rolling correlations).例如,计算两种商品销售额之间的3个月的滚动相关性 目录

  2. R语言使用zoo包中的rollapply函数计算两个时间序列数据列之间的滚动相关性(Rolling correlations)、例如,计算两种商品销售额之间的3个月的滚动相关性

    R语言时间序列数据滚动相关性分析(Rolling correlations).R语言使用zoo包中的rollapply函数计算两个时间序列数据列之间的滚动相关性(Rolling correlation ...

  3. wps excel 中将一行多列数据转换为一行两列的格式 的方法函数

    在使用wps excel 整理表格时,我的表格一行有多列内容,我想把这些数据转换为一行两列的格式,在百度上查了很多方法,都很不好用,最后在论坛中看到的方法,借鉴了一下,各位可以参考. 非常重要的一点: ...

  4. mysql分季度统计数据,mysql按日周月季度统计数据

    mysql按日周月季度统计数据 mysql按日.周.月.季度统计数据 1.使用DATE_FORMAT做等值条件查询 2.DATE_FORMAT函数语法,参考w3school 3.可使用格式 4.使用示 ...

  5. python中使用zip函数基于两个列表数据list创建字典dict数据(Create a dictionary by passing the output of zip to dict)

    python中使用zip函数基于两个列表数据list创建字典dict数据(Create a dictionary by passing the output of zip to dict) 目录

  6. mysql排序显示行数的语句_MySQL中sql语句count(*),orderby,随机数据展示。

    count(*)这么慢,我该怎么办? MyISAM 引擎把一个表的总行数存在了磁盘上,因此执行 count(*) 的时候会直接返回这个数,效率很高: 而 InnoDB 引擎就麻烦了,它执行 count ...

  7. mysql中数据表null什么意思_MySQL 中NULL和空值的区别是什么?

    展开全部 空值是不占用空间的,MySQL中的NULL其实是占用空间的. 不过在MySQL数据库中执行62616964757a686964616fe78988e69d8331333363396466SQ ...

  8. mysql数据导入导出 CSV格式_MySQL中导入导出CSV格式数据

    原标题:MySQL中导入导出CSV格式数据 预备阅读:MySQL中的主键问题和赋权限问题 今天来讲一下在MySQL中导入和导出CSV格式数据的操作. CSV格式数据 逗号分隔值(Comma-Separ ...

  9. mysql 过程 的函数的区别是什么意思_Mysql中存储过程和函数的区别是什么

    Mysql中存储过程和函数的区别是什么 发布时间:2020-12-03 10:01:49 来源:亿速云 阅读:105 作者:小新 这篇文章主要介绍了Mysql中存储过程和函数的区别是什么,具有一定借鉴 ...

最新文章

  1. 2007年度最具投资价值100强网站揭晓——博客园榜上有名
  2. 有没有一种让人很爽的学习方法?
  3. 单播 广播 组播_【技术解析】关于组播概念那些你需要知道的~
  4. HDU 3072 SCC Intelligence System
  5. MVC上传文件受限制
  6. jqery 实现滚动图片【三】
  7. DeepMind和Unity合作,创建虚拟世界来训练AI
  8. nessus 命令行新建用户_【笔记3】命令行基础
  9. 安装linux下显卡驱动
  10. 计算机组成原理实验数据通路,《计算机组成原理》实验报告——数据通路
  11. 嵌入式系统开发笔记16:CJ/T-188 冷热量表协议解析5
  12. 电影《寒战2》中的管理知识
  13. 关于计算机软件的研究生就业,计算机软件与理论研究生毕业就业方向
  14. Win11如何自动清理垃圾?Win11自动删除文件设置方法
  15. 性能调优--gzip、缓存、content-download、逐针渲染、Queueing、动态延迟加载、最小化主线程工作
  16. JSP——JSTL定制标签 - 递归标签显示属性结构
  17. vue列表渲染中key的作用_列表渲染和Vue的v-for指令
  18. Matlab:实现Fra单缝衍射仿真
  19. iOS10.0-10.2越狱图文教程
  20. 8.EP4CE10F17的DDS

热门文章

  1. 旧文新发之十----滨河大道《诗词联碑》序
  2. DSRC与LTE-V2X的区别简述
  3. 微信小程序—数据缓存
  4. aoc显示器测试软件,aoc显示器最佳设置【AOC U27U2显示器评测】
  5. 微信小程序支付接口报错:appid和openid不匹配
  6. from表单el-form-item绑定值为数组的prop写法
  7. JOJ1064: Caeser Comes Back
  8. 有个清华妈妈的教育方法值得借鉴
  9. 工业互联网2022:第一梯队成型、专精玩家突围
  10. docker与容器文件传输