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

如何用T-SQL查询出勤所有指定日期的用户ID

高效查询全勤指定日期用户的SQL方案

问题背景

现有WorkRecords表结构及示例数据如下:

UserIDDateWorked
111111'2023/09/01'
222222'2023/09/01'
333333'2023/09/02'
222222'2023/09/02'
111111'2023/09/02'
333333'2023/09/01'
111111'2023/09/03'

需查询出勤了所有指定日期的UserID(比如示例中需找出同时出勤2023/09/01、09/02、09/03的用户,结果为111111),当前采用CTE加多个UNION的方式性能极差,需要更高效的实现方案。

最优实现方式

核心思路:通过分组统计用户匹配指定日期的唯一记录数,与指定日期的总数做对比,匹配的即为全勤用户。

通用SQL写法(支持动态指定日期)

-- 定义需要检查的指定日期集合
WITH RequiredDates AS (
    SELECT '2023/09/01' AS DateVal UNION ALL
    SELECT '2023/09/02' UNION ALL
    SELECT '2023/09/03'
)
SELECT wr.UserID
FROM WorkRecords wr
JOIN RequiredDates rd ON wr.DateWorked = rd.DateVal
GROUP BY wr.UserID
-- 统计用户匹配到的指定日期数量,等于需要的日期总数则为全勤
HAVING COUNT(DISTINCT wr.DateWorked) = (SELECT COUNT(*) FROM RequiredDates);

简化写法(固定日期场景)

如果指定日期是固定值,可直接硬编码日期总数,省略CTE:

SELECT UserID
FROM WorkRecords
WHERE DateWorked IN ('2023/09/01', '2023/09/02', '2023/09/03')
GROUP BY UserID
HAVING COUNT(DISTINCT DateWorked) = 3;

性能优化关键点

  1. 添加复合索引:在WorkRecords表上创建(DateWorked, UserID)的复合索引,让数据库快速筛选指定日期的记录,同时避免分组时的全表扫描:
    CREATE INDEX idx_workrecords_date_user ON WorkRecords(DateWorked, UserID);
    
  2. 移除DISTINCT(可选):如果(UserID, DateWorked)是唯一约束(同一用户同一天无重复记录),可将COUNT(DISTINCT DateWorked)改为COUNT(*),进一步提升统计效率。

方案优势对比

原CTE+UNION方案会生成大量中间结果,且多次扫描表;本方案仅扫描一次指定日期范围内的记录,通过分组统计直接过滤,逻辑简洁,数据库能更好地利用索引优化执行计划,性能提升显著。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 05:27:27