1. 程式人生 > 實用技巧 >Mysql查詢一段時間內資料,空資料預設為0

Mysql查詢一段時間內資料,空資料預設為0

此文章共分為5部分:  

    1、需求

    2、第一步:資料表查詢

    3、第二步:日期表查詢

    4、第三步:時間表/資料表關聯查詢

    5、第四步:使用mybatis動態控制查詢日期區間

正文開始

需求:

  查詢一段時間內 每天資料量 ,沒有資料預設為0

第一步:資料表查詢

  分組查詢sql如下,查詢 2020-12-20 ~ 2020-12-25 區間資料:  

select count(*) count,DATE_FORMAT(ride_time,'%Y-%m-%d') ride_time 
from tab_visitor_ride_record
where ride_time >=
DATE_FORMAT('2020-12-20','%Y-%m-%d') and ride_time <= DATE_FORMAT('2020-12-25','%Y-%m-%d') group by DATE_FORMAT(ride_time,'%Y-%m-%d')

  結果只會出現已有日期的資料:

  

  以上結果顯然是不符合需求的,那麼就需要連結日期表進行關聯查詢

第二步: 日期表查詢

  日期表查詢如下,需要指定開始日期以及查詢日期天數

select date_add('2020-12-20',interval @i:=@i+1 day) as date 
from (
    select
1 union all select 1 union all select 1 union all select 1 union all select 1 union all select 1 ) as tmp, (select @i:= -1) t

  結果返回 2020-12-20~2020-12-25 區間所有日期:

  

第三步:時間表/資料表關聯查詢

  使用左外聯接查詢:

select d.date, IFNULL(T.count,0) count from 
(
    select date_add('2020-12-20',interval @i
:=@i+1 day) as date from ( select 1 union all select 1 union all select 1 union all select 1 union all select 1 union all select 1 ) as tmp, (select @i:= -1) t ) d left join( select count(*) count,DATE_FORMAT(ride_time,'%Y-%m-%d') ride_time from tab_visitor_ride_record where ride_time >= DATE_FORMAT('2020-12-20','%Y-%m-%d') and ride_time <= DATE_FORMAT('2020-12-25','%Y-%m-%d') group by DATE_FORMAT(ride_time,'%Y-%m-%d') ) T on T.ride_time = d.date GROUP BY d.date

  結果如下:

  

第四步:使用mybatis動態控制查詢日期區間

  首先要動態控制日期,就要知道範圍內的日期個數,建立查詢條件為陣列:  

private String[] days;

  這裡在service層計算:

//計算時間天數跨度
query.setDays(new String[(int) ((query.getEndTime().getTime() - query.getStartTime().getTime()) / (1000 * 60 * 60 * 24))]);

  然後在mapper檔案中通過foreach進行遍歷:

<select id="select" resultMap="Vo">
        select d.date, IFNULL(T.count,0) count
         from
        (
            select date_add(DATE_FORMAT(#{startTime},'%Y-%m-%d'),interval @i:=@i+1 day) as date
            from (
            select 1
            <foreach item="index" collection="days">
                union all select 1
            </foreach>
            ) as tmp,
            (select @i:= -1) t
        ) d
        left join (
            /** 你自己的業務邏輯 */
        )T on T.date = d.date
</select>        

  完結撒花