CASE 添加 max() 便会报错 能否优化?

问题相关代码,请勿粘贴截图 :

            SELECT
                U.USER_NAME,
                R.ID,
                R.SIGN_ADDRESS,
                R.CREATE_TIME,
            CASE
                    WHEN MIN(DATE_FORMAT( R.CREATE_TIME, '%H%i' ))  > 0830 THEN '迟到' 
                    WHEN MAX(DATE_FORMAT( R.CREATE_TIME, '%H%i' ))  < 1830 THEN '早退' 
                     ELSE '正常打卡' 
                        END 
                        FROM
                            T_REMOTE_SIGN_DETAILS R
                            LEFT JOIN T_USER U ON U.ID = R.USER_ID
                            LEFT JOIN T_SCHOOL S ON S.ID = U.SCHOOL_ID 
                        WHERE
                            DATE_FORMAT( R.CREATE_TIME, '%Y%M' ) = DATE_FORMAT( NOW(), '%Y%M' ) 
                            AND S.ID = '270000000109' 
运行结果及报错内容 : > 1140 - In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'ykt_csp.U.user_name'; this is incompatible with sql_mode=only_full_group_by
尝试得其他解决办法 :
CASE
        
        WHEN DATE_FORMAT( R.CREATE_TIME, '%H%i' ) BETWEEN 0730 AND 0830 THEN '上班打卡' 
        WHEN DATE_FORMAT( R.CREATE_TIME, '%H%i' ) BETWEEN 1800 AND 2000 THEN '下班打卡' 
          ELSE '打卡异常' 
            END 

我想要达到的结果 : CASE 添加 max() 便会报错 能否优化?

建议先描述一下你的场景,你目前这个sql语法是有问题的,如果用max或者min这样的聚合函数,而且不开窗,而且有分组字段,那么必须要使用group by .
而且就算你这个sql能跑出数据,应该也不是你想要的数据,所以问题点并不在于case when和聚合函数一起用是否会报错,而是应该选择何种方式来实现你需要的场景。
我先猜一下你的需求,你这个数据应该是个考勤打卡的流水记录,先暂时不管是否存在短时间内多次打卡的情况,以及是否有漏打卡的情况,即肯定有一条上班有一条下班,根据你sql的意思,应该是想保留当前查询的所有行,然后加一个字段识别这个人这一天是否存在迟到或者早退的情况,但这个判断的依据又不仅仅只是看本行数据,需要跨行,那么这个时候,理所应当的就要想到开窗函数了。

SELECT
                U.USER_NAME,
                R.ID,
                R.SIGN_ADDRESS,
                R.CREATE_TIME,
            CASE
                    WHEN MIN(DATE_FORMAT( R.CREATE_TIME, '%H%i' )) over(partition by U.USER_NAME)  > 0830 THEN '迟到' 
                    WHEN MAX(DATE_FORMAT( R.CREATE_TIME, '%H%i' )) over(partition by U.USER_NAME)  < 1830 THEN '早退' 
                     ELSE '正常打卡' 
                        END 
                        FROM
                            T_REMOTE_SIGN_DETAILS R
                            LEFT JOIN T_USER U ON U.ID = R.USER_ID
                            LEFT JOIN T_SCHOOL S ON S.ID = U.SCHOOL_ID 
                        WHERE
                            DATE_FORMAT( R.CREATE_TIME, '%Y%M' ) = DATE_FORMAT( NOW(), '%Y%M' ) 
                            AND S.ID = '270000000109'

但是,mysql要8.0以上版本才支持,否则你就得写个子查询先把最小最大查出来,再去关联到原数据了

你都没分组 不能用聚合的


 SELECT
                U.USER_NAME,
                R.ID,
                R.SIGN_ADDRESS,
                R.CREATE_TIME,
            CASE
                    WHEN MIN(DATE_FORMAT( R.CREATE_TIME, '%H%i' ))  > 0830 THEN '迟到' 
                    WHEN MAX(DATE_FORMAT( R.CREATE_TIME, '%H%i' ))  < 1830 THEN '早退' 
                     ELSE '正常打卡' 
                        END 
                        FROM
                            T_REMOTE_SIGN_DETAILS R
                            LEFT JOIN T_USER U ON U.ID = R.USER_ID
                            LEFT JOIN T_SCHOOL S ON S.ID = U.SCHOOL_ID 
                        WHERE
                            DATE_FORMAT( R.CREATE_TIME, '%Y%M' ) = DATE_FORMAT( NOW(), '%Y%M' ) 
                            AND S.ID = '270000000109' 
                       GROUP BY  U.USER_NAME, R.ID,  R.SIGN_ADDRESS, R.CREATE_TIME