日期变更时如何在用户连接历史表格中展示当日时长合计行?
实现按用户+日期分组插入每日总连接时长行的方案
1 后端SQL调整
首先调整SQL逻辑,原SQL的窗口函数是全局按日期汇总,需要改为按用户+日期分区统计单个用户当日的总时长,同时新增标记字段和排序规则,减少前端计算量:
... String sql = "select TRIM(e.nomemploye) || CASE WHEN e.nomemploye IS NULL OR TRIM(e.nomemploye) = '' THEN '' ELSE ' ' END || e.prenomemploye as user, " + "to_char(h.connexion, 'DD/MM/YYYY HH24:MI:SS') as connex, " + "to_char(h.deconnexion, 'DD/MM/YYYY HH24:MI:SS') as deconnex, " + "to_char(CAST(h.duree_seconde || ' second' AS INTERVAL), 'HH24:MI:SS') as duree, " + // 按用户+日期分区统计该用户当日总连接时长 "to_char(CAST(SUM(h.duree_seconde) OVER (PARTITION BY TRIM(e.nomemploye) || CASE WHEN e.nomemploye IS NULL OR TRIM(e.nomemploye) = '' THEN '' ELSE ' ' END || e.prenomemploye, CAST(h.connexion AS DATE)) || ' second' AS INTERVAL), 'HH24:MI:SS') duree_totale_par_date, " + // 标记当前记录是否是对应用户+日期的最后一条记录 "CASE WHEN ROW_NUMBER() OVER (PARTITION BY TRIM(e.nomemploye) || CASE WHEN e.nomemploye IS NULL OR TRIM(e.nomemploye) = '' THEN '' ELSE ' ' END || e.prenomemploye, CAST(h.connexion AS DATE) ORDER BY h.connexion DESC) = 1 THEN 'true' ELSE 'false' END as is_last_of_user_date " + "from employe e join utilisateur u on e.idemploye = u.idemploye " + "join histodureeconnexion h on h.iduser = u.idutilisateur " + // 按用户、连接时间正序排序,保证记录输出顺序符合预期 "order by user, h.connexion "; ...
2 前端JSP模板调整
使用AngularJS的ng-repeat-start/ng-repeat-end指令,支持单次循环输出多个DOM元素,判断到当前记录是用户当日最后一条时,额外渲染汇总行:
... <table class="table table-hover table-bordered"> <thead> <tr> <th>Utilisateur</th> <th>Date de connexion</th> <th>Date de déconnexion</th> <th>Durée de connexion</th> </tr> </thead> <tbody> <!-- 循环开始,渲染普通连接记录行 --> <tr ng-repeat-start="histoDureeConnex in histoDureeConnexs"> <td>{{histoDureeConnex.user}}</td> <td>{{histoDureeConnex.connex}}</td> <td>{{histoDureeConnex.deconnex == 'null' ? 'Session encore ouverte' : histoDureeConnex.deconnex}}</td> <td>{{histoDureeConnex.duree == 'null' ? '' : histoDureeConnex.duree}}</td> </tr> <!-- 符合条件时插入当日汇总行,可自定义样式区分普通记录 --> <tr ng-if="histoDureeConnex.is_last_of_user_date == 'true'" class="bg-light"> <td colspan="3" style="text-align:right; font-weight:bold;">Total du jour pour {{histoDureeConnex.user}}</td> <td style="font-weight:bold;">{{histoDureeConnex.duree_totale_par_date}}</td> </tr> <!-- 循环结束标识 --> <ng-repeat-end></ng-repeat-end> </tbody> </table> ...
可选兼容方案
如果不想修改后端SQL,也可以在histoDureeConnexController中对返回的记录数组做预处理,遍历所有记录,手动给每条记录添加is_last_of_user_date标记,逻辑和SQL窗口函数完全一致即可。
内容的提问来源于stack exchange,提问作者pheromix
相关产品推荐
相关产品推荐

