概述 ⌨️
在这个业务场景中,我们需要了解当天[包含]的前 6 天每天的总数据。主要是为了数据大屏的展示。在本文中,我们将介绍如何使用SQL查询当天[包含]的前六天每天的总数据
问题产生⁉️
现在我们的系统需要做一个数据大屏的单体应用,这个应用数据是从数据库获取,通过SQL 检索并展示有价值的数据。
主要分了以下模块📦:
获取指定年份的 12 个月每月的总数据量
获取数据总数
获取某个状态值在总数据中的比例
获取今日某个状态的比例
获取数据排行榜
获取超时数据
当天的前七天每天的总数据
问题本质 🧠
这个问题本质上是一个数据查询问题。具体来说,它要求从数据库中检索出获取当前 [包含]前 6 天,在查询过程中,需要使用大部分需要使用日期函数和聚合函数等SQL函数,以及GROUP BY子句和WHERE子句等SQL语句来完成数据筛选和分组操作。
如何解决获取当前前七天每天的总数
先聚合数据库表中已存在的数据,但是这样会存在一个 ’狠’ 明显的问题。只获取了已经存在的数据,我们标题的要求是当天[包含当天] 的前 6 天每天的总数据,意味着即使数据不存在也要显示为 0
SELECT
DATE_FORMAT( comp.create_time, '%m-%d' ) AS time,
COUNT( 1 ) AS count
comp_complain comp
GROUP BY
DATE( comp.create_time )
如何解决查询当数据库不存在的数据
public List<String> getLocalDate (LocalDate today) {
List<String> dateList = new ArrayList<>();
for (int i = 6; i >= 0; i--) {
LocalDate date = today.minusDays(i);
String format = date.format(DateTimeFormatter.ofPattern("MM-dd"));
dateList.add(format);
return dateList;
这段代码的作用是生成一个包含最近 7 天日期的字符串列表。具体来说,这个方法接受一个 LocalDate
类型的参数 today
,表示当前日期。然后,它使用一个循环从当前日期开始,生成最近 7 天的日期,并将这些日期格式化为 MM-dd
的字符串,添加到一个字符串列表中。最后,这个方法返回这个字符串列表。
例如,如果当前日期是 2022 年 5 月 1 日,那么这个方法将会生成包含以下 7 个字符串的列表:
[04-25,04-26,04-27,04-28,04-29,04-30,05-01]
这个字符串列表可以作为参数传递给您的 SQL 查询,以获取最近 7 天的投诉数量统计
SELECT
'04-07' AS date UNION ALL
SELECT
'04-08' AS date UNION ALL
SELECT
'04-09' AS date UNION ALL
SELECT
'04-10' AS date UNION ALL
SELECT
'04-11' AS date UNION ALL
SELECT
'04-12' AS date UNION ALL
SELECT
'04-13' AS date
'引号'内部数据是通过 Mybatis 中的动态 sql 传递进去.
<foreach collection="localDate" separator="UNION ALL" item="date">
SELECT #{date} AS date
</foreach>
最后,根据 Left 的连表机制
在 LEFT JOIN
中,左表中的所有行都会出现在结果中,而右表中没有匹配的行则会用 NULL
值填充。
SELECT ... FROM table1 LEFT JOIN table2 ON table1.column = table2.column;
将动态 7 天的数据使用 Left join 进行关联
SELECT
d.date,
IFNULL( c.count, 0 ) AS count
SELECT
'04-07' AS date UNION ALL
SELECT
'04-08' AS date UNION ALL
SELECT
'04-09' AS date UNION ALL
SELECT
'04-10' AS date UNION ALL
SELECT
'04-11' AS date UNION ALL
SELECT
'04-12' AS date UNION ALL
SELECT
'04-13' AS date
LEFT JOIN (
SELECT
DATE_FORMAT( comp.create_time, '%m-%d' ) AS time,
COUNT( 1 ) AS count
comp_complain comp
GROUP BY
DATE( comp.create_time )
) c ON d.date = c.time;
s