我已经写了这个查询来挑选超时,时间,访问日期和员工的总加班时间,这没关系,但问题是我想获得当月的记录。它实际上从他加入组织到今天的那一天选择了所有月份,但我只想在这个月。
查询:
WITH times
AS (
SELECT t1.EmplID
,t3.EmplName
,min(t1.RecTime) AS InTime
,max(t2.RecTime) AS [TimeOut]
,cast(min(t1.RecTime) AS DATETIME) AS InTimeSub
,cast(max(t2.RecTime) AS DATETIME) AS TimeOutSub
,t1.RecDate AS [DateVisited]
FROM AtdRecord t1
INNER JOIN AtdRecord t2 ON t1.EmplID = t2.EmplID
AND t1.RecDate = t2.RecDate
AND t1.RecTime < t2.RecTime
INNER JOIN HrEmployee t3 ON t3.EmplID = t1.EmplID
GROUP BY t1.EmplID
,t3.EmplName
,t1.RecDate
)
SELECT EmplID
,EmplName
,InTime
,[TimeOut]
,[DateVisited]
,convert(CHAR(5), cast([TimeOutSub] - InTimeSub AS TIME), 108) totaltime
,CONVERT(CHAR(5), CASE
WHEN CAST([TimeOutSub] AS DATETIME) >= '18:00'
AND EmplId NOT IN (
5
,43
,11
,40
,46
,42
,31
)
THEN LEFT(CONVERT(VARCHAR(12), DATEADD(ms, DATEDIFF(ms, CAST('18:00' AS DATETIME), CAST([TimeOutSub] AS DATETIME)), 0), 108), 5)
WHEN CAST([TimeOutSub] AS DATETIME) >= '17:00'
AND EmplId IN (
5
,43
,40
,46
,42
,31
)
THEN LEFT(CONVERT(VARCHAR(12), DATEADD(ms, DATEDIFF(ms, CAST('17:00' AS DATETIME), CAST([TimeOutSub] AS DATETIME)), 0), 108), 5)
ELSE '00:00'
END, 108) AS OVERTIME
FROM times
答案 0 :(得分:2)
这将找到当月的开始和结束:
select dateadd(m, datediff(m, 0, GetDate()), 0),
dateadd(m, datediff(m, -1, GetDate()), 0)
所以基本上添加
WHERE t1.RecDate >= dateadd(m, datediff(m, 0, GetDate()), 0)
AND t1.RecDate < dateadd(m, datediff(m, -1, GetDate()), 0)
此解决方案将允许使用索引,基本上比月(重新创建)和年(重新)建议执行速度快
答案 1 :(得分:1)
您可以使用Date函数
所以你需要在你的条件
中添加它 WHERE MONTH(t1.RecDate) = MONTH(GetDate())
AND
YEAR(t1.RecDate) = YEAR(GetDate())
试试这个
WITH times
AS (
SELECT t1.EmplID
,t3.EmplName
,min(t1.RecTime) AS InTime
,max(t2.RecTime) AS [TimeOut]
,cast(min(t1.RecTime) AS DATETIME) AS InTimeSub
,cast(max(t2.RecTime) AS DATETIME) AS TimeOutSub
,t1.RecDate AS [DateVisited]
FROM AtdRecord t1
INNER JOIN AtdRecord t2 ON t1.EmplID = t2.EmplID
AND t1.RecDate = t2.RecDate
AND t1.RecTime < t2.RecTime
INNER JOIN HrEmployee t3 ON t3.EmplID = t1.EmplID
WHERE MONTH(t1.RecDate) = MONTH(GetDate())
AND
YEAR(t1.RecDate) = YEAR(GetDate())
GROUP BY t1.EmplID
,t3.EmplName
,t1.RecDate
)
SELECT EmplID
,EmplName
,InTime
,[TimeOut]
,[DateVisited]
,convert(CHAR(5), cast([TimeOutSub] - InTimeSub AS TIME), 108) totaltime
,CONVERT(CHAR(5), CASE
WHEN CAST([TimeOutSub] AS DATETIME) >= '18:00'
AND EmplId NOT IN (
5
,43
,11
,40
,46
,42
,31
)
THEN LEFT(CONVERT(VARCHAR(12), DATEADD(ms, DATEDIFF(ms, CAST('18:00' AS DATETIME), CAST([TimeOutSub] AS DATETIME)), 0), 108), 5)
WHEN CAST([TimeOutSub] AS DATETIME) >= '17:00'
AND EmplId IN (
5
,43
,40
,46
,42
,31
)
THEN LEFT(CONVERT(VARCHAR(12), DATEADD(ms, DATEDIFF(ms, CAST('17:00' AS DATETIME), CAST([TimeOutSub] AS DATETIME)), 0), 108), 5)
ELSE '00:00'
END, 108) AS OVERTIME
FROM times
答案 2 :(得分:1)
将您的CTE改为:
WITH times
AS (
SELECT t1.EmplID
,t3.EmplName
,min(t1.RecTime) AS InTime
,max(t2.RecTime) AS [TimeOut]
,cast(min(t1.RecTime) AS DATETIME) AS InTimeSub
,cast(max(t2.RecTime) AS DATETIME) AS TimeOutSub
,t1.RecDate AS [DateVisited]
FROM AtdRecord t1
INNER JOIN AtdRecord t2 ON t1.EmplID = t2.EmplID
AND t1.RecDate = t2.RecDate
AND t1.RecTime < t2.RecTime
INNER JOIN HrEmployee t3 ON t3.EmplID = t1.EmplID
WHERE MONTH(t1.RecDate)=MONTH(Getdate())
AND YEAR (t1.RecDate)=YEAR(Getdate())
GROUP BY t1.EmplID
,t3.EmplName
,t1.RecDate
)
请注意,如果您在任何月份的第一天运行此操作,您将只获取当天的数据,而不是上个月的数据。
答案 3 :(得分:0)
这非常简单,只需获取要比较的两个日期的月份即可,但是两个日期都应采用日期格式,或者必须使用日期格式进行投射
获取任意日期的月份MONTH()方法
MONTH('2019/02/22')
它将仅返回该日期的月份,只是通过month方法传递日期。
如果您的日期采用varchar或字符串格式,则应采用日期格式
CAST('2019/02/22'AS DATE)
完整示例是
MONTH(CAST(YourDate AS DATE)) = MONTH(GETDATE())