仅获取当月的记录

时间:2014-01-30 09:38:23

标签: sql sql-server sql-server-2008 tsql sql-server-2012

我已经写了这个查询来挑选超时,时间,访问日期和员工的总加班时间,这没关系,但问题是我想获得当月的记录。它实际上从他加入组织到今天的那一天选择了所有月份,但我只想在这个月。

查询:

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

4 个答案:

答案 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())