最近写查询遇到这样一个情况。我需要查到一段时间(比如2015-06-15到2015-07-01)内每一天的总价格。
可当我写sql查询的时候,发现如果一天没有内容,那么这一天的数据将不会被sql查出来,意味着从开始到结束的日期中可能会有中断。
1 | select DATE_FORMAT( cast(created_at as date), '%Y-%m-%d') as date, count(*) as num from |
这样的查询结果如下:1
2
3
4
5
6
7
8
92015-06-22 2
2015-06-23 25
2015-06-24 60
2015-06-25 41
2015-06-26 65
2015-06-27 72
2015-06-28 81
2015-06-29 87
2015-06-30 59
发现中间没有数据的日期没被正确填充。
在经过一番了解之后找到了一个比较靠谱的做法,如下:
首先根据这个 PROCEDURE 创建一个PROCEDURE 并插入数据
1 | DROP PROCEDURE IF EXISTS FillCalendar; |
插入完成之后就可以将calendar
表和order
表进行连接,在order表中缺少的字段,默认取0。这里应用了一个SQL的函数 COALESCE
插入完后calendar表内容:1
2
3
4
5
6
7date
----------
2000-01-01
2000-01-02
...
2015-12-30
2050-12-31
COALESCE函数的作用
返回其参数中第一个非空表达式
1 | select a.date ,COALESCE(b.num, 0) num from calendar a |
这样得到的输出:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
172015-06-15 0
2015-06-16 0
2015-06-17 0
2015-06-18 0
2015-06-19 0
2015-06-20 0
2015-06-21 0
2015-06-22 2
2015-06-23 25
2015-06-24 60
2015-06-25 41
2015-06-26 65
2015-06-27 72
2015-06-28 81
2015-06-29 87
2015-06-30 59
2015-07-01 0
这个问题一开始纠结了比较久,原因是在找有没有不加calendar表能做到同样的效果。还有那个COALESCE函数的用法。