如何用SQL查询Freeradius数据库中特定时间段全程离线的用户
找出Freeradius中指定日期全程离线的用户
你的原查询逻辑存在漏洞,它只检查了会话开始时间不在目标区间且有结束时间,但无法排除那些会话跨到目标区间的用户(比如2月登录、3月才下线),也没考虑用户可能存在多个会话的情况。以下是正确的查询方案:
方案1:仅从radacct表筛选(适用于只关注有过登录记录的用户)
这个查询会排除所有在2024年3月期间有过在线状态的用户,剩下的就是全程离线的用户:
SELECT DISTINCT ra.username FROM radacct ra WHERE ra.username NOT IN ( SELECT DISTINCT username FROM radacct WHERE -- 会话开始在3月内 acctstarttime BETWEEN '2024-03-01 00:00:00' AND '2024-03-31 23:59:59' OR -- 会话跨到3月(开始在3月前,但结束在3月后或未结束) (acctstarttime < '2024-03-01' AND (acctstoptime IS NULL OR acctstoptime > '2024-03-01')) )
方案2:结合用户表(包含从未登录过的用户)
如果你的数据库有存储所有注册用户的表(比如radcheck),可以用这个查询把从未登录过的用户也包含进来:
SELECT rc.username FROM radcheck rc WHERE rc.username NOT IN ( SELECT DISTINCT username FROM radacct WHERE acctstarttime BETWEEN '2024-03-01 00:00:00' AND '2024-03-31 23:59:59' OR (acctstarttime < '2024-03-01' AND (acctstoptime IS NULL OR acctstoptime > '2024-03-01')) )
为什么原查询会返回2月29日登录的用户?
原查询的acctstarttime NOT BETWEEN '2024-03-01' AND '2024-03-31'会包含所有在3月前开始的会话,只要这些会话有结束时间(acctstoptime IS NOT NULL)就会被返回。但其中部分用户可能在3月期间还有其他活跃会话(比如3月内新登录),原查询没过滤这种情况,导致错误返回;另外,如果用户在2月29日登录、3月1日才下线,这类用户在3月有在线时间,原查询也会错误返回他们。
内容的提问来源于stack exchange,提问作者user23962757
相关产品推荐
相关产品推荐

