如何將一個按天統計的sql批量查詢?


最近遇到一個需求,要按天統計一些數據,但之前系統已經運行大半年了,需要把之前的數據也做一個統計:

  於是剛開始我是這樣寫的:

public void autoSaveData(RentalCostReportQueryVO queryVo) {
        Date startTime;
        Date endTime;
        if (queryVo.getStartTime() == null || queryVo.getEndTime() == null) {
            startTime = DateUtils.getCurrentDate();
            endTime = DateUtils.getCurrentDate();
        } else {
            startTime = queryVo.getStartTime();
            endTime = queryVo.getEndTime().before(DateUtils.getCurrentDate()) ? queryVo.getEndTime() : DateUtils.getCurrentDate();
        }

        Calendar startCalendar = Calendar.getInstance();
        Calendar endCalendar = Calendar.getInstance();
        startCalendar.setTime(startTime);
        endCalendar.setTime(endTime);
        List<RentalCostReport> rentalCostReportList = new ArrayList<>();
        List<Date> dateList = new ArrayList<>();
        do {
            Date currentTime = startCalendar.getTime();
       //此處是循環執行的查詢
List<RentalCostReport> rentalCostReportList1 = rentalCostMapper.queryRentalCostByDay(currentTime); //日期加1 startCalendar.add(Calendar.DAY_OF_MONTH, 1); //當前日期和結束日歷日期比較,超過結束日期則終止 } while (!startCalendar.after(endCalendar)); List<RentalCostReport> rentalCostReportList2 = rentalCostMapper.queryFmAttendanceBlock(queryVo) .stream().filter(item -> null != item.getId()).collect(Collectors.toList()); List<RentalCostReport> rentalCostReportList3 = rentalCostMapper.queryStoreAndDeliverReport(queryVo); mergeRentalCostReportList(rentalCostReportList, rentalCostReportList2, rentalCostReportList3); if (CollectionUtils.isNotEmpty(rentalCostReportList)) { for (RentalCostReport rentalCostReport : rentalCostReportList) { rentalCostReport.setId(rentalCostReport.getId() + rentalCostReport.getLeaseCode()); } rentalCostMapper.batchSaveOrUpdate(rentalCostReportList); } }

其實很簡單就是把某個時間段內遍歷出具體是哪一天  ,然后把這個具體的天當做參數傳遞到mapper中,然后就循環查出每一天的集合 ,再把集合累加

  

    do {
            Date currentTime = startCalendar.getTime();
       //此處是循環執行的查詢 List<RentalCostReport> rentalCostReportList1 = rentalCostMapper.queryRentalCostByDay(currentTime); //日期加1 startCalendar.add(Calendar.DAY_OF_MONTH, 1); //當前日期和結束日歷日期比較,超過結束日期則終止 } while (!startCalendar.after(endCalendar));

這是一種做法,但這種做法很耗費時間,比如我要查詢一年按天的統計就會循環執行365次,很耗費時間,於是我就在想,怎樣能夠批量傳參(List<Date> 這個集合當中包含了具體的日期)然后批量返回結果

  思路:在sql中 有個UNION 關鍵字  他是把相同結構的字段 合並返回

  比如 SELECT #{currentDate} dateTime FROM A WHERE begin_time <= #{currentTime} AND end_time >= #{currentTime} 

  #{currentTime} 代表的是由mybatis傳進來的參數  比如我傳參進來是 ‘2020-05-04’ 但這個只能查詢一天的

  SELECT ‘2020-05-04’ dateTime FROM A WHERE begin_time <= ‘2020-05-04’ AND end_time >= ‘2020-05-04’

  SELECT ‘2020-05-05’ dateTime FROM A WHERE begin_time <= ‘2020-05-05’ AND end_time >= ‘2020-05-05’

  如上我如果要查詢 ‘2020-05-05’ 就需要循環查詢一次

  但我用UNION 把他們連接起來呢?

  SELECT ‘2020-05-04’ dateTime FROM A WHERE begin_time <= ‘2020-05-04’ AND end_time >= ‘2020-05-04’

  UNION 

  SELECT ‘2020-05-05’ dateTime FROM A WHERE begin_time <= ‘2020-05-05’ AND end_time >= ‘2020-05-05’

  這樣就可以一次性查出來了

  由此悟出來我可以使用Mybatis的 foreach 標簽來循環一個集合 用UNION把他們聯合起來,就形成了批量查詢:

<select id="batchQueryRentalCostByDay" 
    resultType
="com.hope.saas.wms.entity.decision.report.RentalCostReport"> <foreach collection="list" item="currentTime" index="index" separator=" UNION "> SELECT CONCAT( a.tenant_id, b.temperature_layer_code, STR_TO_DATE( #{currentTime}, '%Y-%m-%d' )) id, STR_TO_DATE( #{currentTime}, '%Y-%m-%d' ) dateTime, b.temperature_layer_name temperatureLayerName, b.temperature_layer_code temperatureLayerCode, a.tenant_id tenantId, a.tenant_name tenantName FROM warehouse_lease_contract a LEFT JOIN leasing_information b ON a.id = b.warehouse_lease_contract_id WHERE begin_time &lt;= #{currentTime} AND end_time >= #{currentTime} AND status_code = 1 GROUP BY lease_code, b.temperature_layer_code, a.tenant_id </foreach> </select>

 

  運行起來效率相當快!

  

  

 
        
 
        

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM