group by and union all

sql 复制代码
 SELECT
        'vacation' AS keyCode,
        staff.staff_id AS staffId,
        staff.staff_name AS staffName,
        SUM(DATEDIFF(LEAST(staff.end_time, #{endDate}), GREATEST(staff.begin_time, #{startDate}))) AS vacationDays,
        NULL AS lateDays,
        NULL AS absenceDays,
        NULL AS attendanceDays
        FROM tb_staff_stop_receive_time AS staff
        WHERE staff.stop_type = 1
        AND (staff.begin_time BETWEEN #{startDate} AND #{endDate} OR staff.end_time BETWEEN #{startDate} AND #{endDate})
        GROUP BY staff.staff_id

        UNION ALL

        SELECT
        'late' AS keyCode,
        staff.id AS staffId,
        staff.staff_name AS staffName,
        NULL AS vacationDays,
        COUNT(*) AS lateDays,
        NULL AS absenceDays,
        NULL AS attendanceDays
        FROM tb_staff_stop_receive_time AS staff
        JOIN eb_store_order AS O ON staff.id = O.delivery_id
        WHERE O.staff_late = 1
        AND O.create_time BETWEEN #{startDate} AND #{endDate}
        GROUP BY staff.id

        UNION ALL

        SELECT
        'absence' AS keyCode,
        staff.id AS staffId,
        staff.staff_name AS staffName,
        NULL AS vacationDays,
        NULL AS lateDays,
        COUNT(*) AS absenceDays,
        NULL AS attendanceDays
        FROM tb_staff_stop_receive_time AS staff
        JOIN eb_store_order AS O ON staff.id = O.delivery_id
        WHERE O.status NOT IN (2, 3, 4, 5) AND O.order_service_time < CURRENT_TIMESTAMP
        AND O.create_time BETWEEN #{startDate} AND #{endDate}
        GROUP BY staff.id

        UNION ALL

        SELECT
        'attendance' AS keyCode,
        staff.id AS staffId,
        staff.staff_name AS staffName,
        NULL AS vacationDays,
        NULL AS lateDays,
        NULL AS absenceDays,
        COUNT(*) AS attendanceDays
        FROM tb_staff_stop_receive_time AS staff
        JOIN eb_store_order AS O ON staff.id = O.delivery_id
        WHERE O.status = 2
        AND O.create_time BETWEEN #{startDate} AND #{endDate}
        GROUP BY staff.id
java 复制代码
    /*同比出勤*/
    List<AbsenceThisWeekVo> getAbsenceThisWeek(@Param("startDate") LocalDate startDate, @Param("endDate") LocalDate endDate);
java 复制代码
        int totalAbsenceCount = lateOrders.stream()
                .filter(order -> order.getState() == 0 || order.getState() == 1)
                .mapToInt(AbsenceThisWeekVo::getCount)
                .sum();
        //未出勤的
        int totalAbsenceCountLast = lateOrders.stream()
                .filter(order -> order.getState() == 2 || order.getState() == 3
                        || order.getState() == 4 || order.getState() == 5)
                .mapToInt(AbsenceThisWeekVo::getCount)
                .sum();
java 复制代码
    public String getStaffPercentage(double count, double totalCount){

        String rate = "0%";


        if (totalCount == 0) {

            throw new RuntimeException("分母/数据为0,无法计算!");
        } else {
            // 使用BigDecimal进行精确的数值计算
            BigDecimal countBD = BigDecimal.valueOf(count);
            BigDecimal totalCountBD = BigDecimal.valueOf(totalCount);

            // 计算百分比
            BigDecimal percentageBD = NumberUtil.div(countBD.toString(), totalCountBD.toString(), 2)
                    .multiply(BigDecimal.valueOf(100));

            rate = percentageBD.intValue() + "%";
        }


        return rate;
    }
java 复制代码
    public List<StaffAttendanceResponse> getStaffAttendance(Date startDate, Date endDate) {

//会查询出一个id有多条记录,要做的就是,将这些多条的数据,根据唯一id合成一条完整的
        List<StaffAttendanceResponse> attendanceDaysList2 = statisticsStaffDao.getAttendanceDays(startDate, endDate);

        // 创建一个 Map 用于存储每个员工的 StaffAttendanceResponse
        Map<Integer, StaffAttendanceResponse> responseMap = new HashMap<>();
        for (StaffAttendanceResponse response : attendanceDaysList2) {
            Integer  staffId = response.getStaffId();

            StaffAttendanceResponse individualResponse;

            if (CollectionUtil.isNotEmpty(responseMap) &&responseMap.containsKey(staffId) ) {
                individualResponse = responseMap.get(staffId);
            } else {
                individualResponse = new StaffAttendanceResponse();
                BeanUtils.copyProperties(response,individualResponse);
            }

            // 没有id创建一个新的 StaffAttendanceResponse 对象
//           StaffAttendanceResponse individualResponse = responseMap.getOrDefault(staffId, new StaffAttendanceResponse());

            switch (response.getKeyCode()) {
                case "vacation":
                    individualResponse.setVacationDays(response.getVacationDays());
                    break;
                case "late":
                    individualResponse.setLateDays(response.getLateDays());
                    break;
                case "absence":
                    individualResponse.setAbsenceDays(response.getAbsenceDays());
                    break;
                case "attendance":
                    individualResponse.setAttendanceDays(response.getAttendanceDays());
                    break;
                default:
                   throw new ServiceException("数据错误!");


            }
            // 更新 Map
            responseMap.put(staffId, individualResponse);
        }
        // 转换 Map 的值为 List 并返回
        return new ArrayList<>(responseMap.values());
    }


   List<StaffAttendanceResponse> attendanceResponse = getVacationDaysByType(type,this::getStaffAttendance);
        StaffCircleVo StaffCircleResponse = getVacationDaysByType(typeCircle,this::getTotalVacationDays);

得到固定时间

java 复制代码
    public interface StaffAttendanceFetcher<T>  {
        T fetch(Date startDate, Date endDate);
    }

    public <T> T getVacationDaysByType(String type, StaffAttendanceFetcher<T> fetcher) {
        Calendar cal = Calendar.getInstance();
        Date start = null, end = null;
        switch (type) {
            case "TODAY":
                LocalDateTime startOfDay = LocalDate.now().atStartOfDay();
                LocalDateTime endOfDay = LocalDate.now().atTime(23, 59, 59);
                start = Date.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant());
                end = Date.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant());
                break;
            case "WEEK":
                cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
                start = cal.getTime();
                cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
                end = cal.getTime();
                break;
            case "MONTH":
                cal.set(Calendar.DAY_OF_MONTH, 1);
                start = cal.getTime();
                cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
                end = cal.getTime();
                break;
            case "YEAR":
                cal.set(Calendar.DAY_OF_YEAR, 1);
                start = cal.getTime();
                cal.set(Calendar.DAY_OF_YEAR, cal.getActualMaximum(Calendar.DAY_OF_YEAR));
                end = cal.getTime();
                break;
            default:
                throw new IllegalArgumentException("请输入正确的参数: " + type + "TODAY,WEEK, MONTH, YEAR.");

        }
        return fetcher.fetch(start, end);
    }
相关推荐
余槐i6 小时前
PostgreSQL 函数索引报错 must be immutable:3种绕法与代价
数据库·后端·sql·postgresql·性能优化
数据库小学妹6 小时前
PostgreSQL表膨胀怎么办?autovacuum清不动的根因与排查命令
数据库·postgresql·表膨胀·mvcc·数据库运维
mister_guo6 小时前
MySQL-1267错误:排序规则冲突的原因与解决方案
数据库·mysql
骇客野人6 小时前
在麒麟操作系统上 分别安装 jdk1.8, 达梦数据库,redis ,memcache 的操作实施方案和步骤
数据库·redis·memcached
美狐美颜SDK开放平台8 小时前
直播APP如何实现美白滤镜功能?视频美颜SDK技术开发方案详解
前端·数据库·人工智能·音视频·美颜sdk·直播美颜sdk·视频美颜sdk
花间相见9 小时前
【计算基础|MySQL01】【上手】安装连接、数据类型与建库建表
数据库·后端
花间相见10 小时前
【计算基础|MySQL02】【上手】SQL 增删改查
数据库·后端
ITxiaobing202310 小时前
IP 库与 AppsFlyer 国家/地区数据不一致,如何系统地对账?
数据库·网络协议·tcp/ip
这个DBA有点耶10 小时前
从时间到语义:时序数据库与向量数据库的核心机制、选型与多模融合趋势
数据库·mysql·架构
对空六课10 小时前
RFM分层边界变化的回溯计算
大数据·服务器·前端·数据库·人工智能·算法·数据分析