You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

考勤系统开发:按用户组与出勤状态展示用户的SQL问题

解决考勤系统用户重复展示问题

问题原因

你遇到的重复展示问题核心在于关联marks表时未限定目标会议日期,或条件放置位置错误:

  • 第一个查询未限定marks.meeting_date,会把用户所有历史出勤记录关联出来,一条出勤记录对应一条用户数据,导致重复;
  • 第二个查询把m.meeting_date = '2023-02-01'放到WHERE子句,会将LEFT JOIN转为INNER JOIN,丢失未标记出勤的用户,若用户当天有多条标记记录,仍会重复。

正确SQL写法

需要同时关联三张表,且将marks的日期条件放到JOIN的ON子句中,确保每个用户仅关联当天的出勤记录,同时保留该组所有用户:

SELECT 
    u.id,
    u.first_name,
    m.status AS attendance_status
FROM users u
-- 关联会议表,确保仅查询当天有会议的组用户
INNER JOIN attendance_schedules s 
    ON u.group_name = s.group_name 
    AND s.meeting_date = '2023-02-01'
-- 左关联当天的出勤记录,仅匹配当天数据,避免多日期导致重复
LEFT JOIN marks m 
    ON u.id = m.user_id 
    AND m.meeting_date = '2023-02-01'
WHERE u.status = 1 
    AND u.group_name = 'servicon'

去重优化

若attendance_schedules中当天该组存在多条会议记录,或用户当天有重复标记,可通过以下两种方式去重:

方式1:使用DISTINCT

SELECT DISTINCT
    u.id,
    u.first_name,
    COALESCE(m.status, '未标记') AS attendance_status
FROM users u
INNER JOIN attendance_schedules s 
    ON u.group_name = s.group_name 
    AND s.meeting_date = '2023-02-01'
LEFT JOIN marks m 
    ON u.id = m.user_id 
    AND m.meeting_date = '2023-02-01'
WHERE u.status = 1 
    AND u.group_name = 'servicon'

方式2:使用GROUP BY聚合

SELECT 
    u.id,
    u.first_name,
    MAX(m.status) AS attendance_status -- 取已存在的标记状态,无标记则为NULL
FROM users u
INNER JOIN attendance_schedules s 
    ON u.group_name = s.group_name 
    AND s.meeting_date = '2023-02-01'
LEFT JOIN marks m 
    ON u.id = m.user_id 
    AND m.meeting_date = '2023-02-01'
WHERE u.status = 1 
    AND u.group_name = 'servicon'
GROUP BY u.id, u.first_name

前端逻辑处理

拿到查询结果后:

  • 若attendance_status为NULL或未标记状态值(比如0),显示「标记出勤」按钮;
  • 若attendance_status为已标记状态值(比如1),切换为「已标记」状态按钮。

内容的提问来源于stack exchange,提问作者Elex Promise

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 06:15:40