如何找到一天的第一时间和一天中的最后一个时间

时间:2013-02-12 18:40:02

标签: sql sql-server sql-server-2005

我有一个查询,抓住第一个打孔的部门中的第一个人,以及最后打了一个部门的人。基本上,这显示我打开了一个位置,并关闭了一个位置。下面是我的查询我正在使用“OVER”函数,但是over函数对VB.net中的数据集不起作用是否还有其他选项来替换over函数?

SELECT * FROM (
    SELECT timeclock.dtTimeIn, timeclock.dtTimeOut, employees.sfirstname,
       RANK() OVER ( ORDER BY dtTimeIn) rk1, --earliest record gets 1
       RANK() OVER (ORDER BY dtTimeOut DESC) rk2 --latest record gets 1

    FROM   TimeClock INNER JOIN
                         Employees ON TimeClock.lEmployeeID = Employees.lEmployeeID
    WHERE (dtTimeIn > dateadd(day, datediff(day, 0, getdate())-1, 0)) AND (dtTimeOut < dateadd(day, datediff(day, 0, getdate()), 0)) AND 
      (sDept IN ('1', '2', '3'))
) A
WHERE rk2=1 

3 个答案:

答案 0 :(得分:2)

您可以将其替换为相关子查询。以下是rk1的示例:

(select count(distinct lEmployeeId)
 from TimeClock tc
 where tc.lEmployeeId = timeclock.lemployeeId and
       tc.dtTimeIn <= timeclock.dtTimeIn
) as rk1

Rank可以生成多个标记为1的记录(当存在关联时)。如果你的意思是row_number(),那么你可以在上面的查询中使用count(*)而不是count(distinct)

答案 1 :(得分:2)

你可以试试这个:

SELECT  tc.dtTimeIn
        , tc.dtTimeOut
        , e.sfirstname
FROM    TimeClock tc
JOIN    Employees e ON tc.lEmployeeID = e.lEmployeeID
JOIN    (               
            SELECT  DATEADD(DAY, DATEDIFF(DAY, 0, tc.dtTimeIn), 0) _date
                    , MIN(tc.dtTimeIn) dtTimeIn
                    , MAX(tc.dtTimeOut) dtTimeOut
            FROM    TimeClock tc
            WHERE   e.sDept IN ('1', '2', '3')
            GROUP BY
                    DATEADD(DAY, DATEDIFF(DAY, 0, tc.dtTimeIn), 0)
) t ON  t._date = DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)
AND     DATEADD(DAY, DATEDIFF(DAY, 0, tc.dtTimeIn), 0) = t._date
AND     (t.dtTimeIn = tc.dtTimeIn OR t.dtTimeOut = tc.dtTimeOut)
WHERE   e.sDept IN ('1', '2', '3')

答案 2 :(得分:1)

您的查询只返回关闭某个位置的人...

返回谁打开以及谁关闭你需要将你的where子句更改为

where rk2 = 1 or rk1 = 1

如果您同时从多个sDept获取订单,则应按顺序对sDept进行分区

RANK() OVER ( partition by sDept ORDER BY dtTimeIn) rk1, --earliest record gets 1
           RANK() OVER ( partition by sDept ORDER BY dtTimeOut DESC) rk2 --latest record get

...见

设置环境以运行查询

    declare @TimeClock table ( lEmployeeID int, dtTimeIn datetime, dtTimeOut datetime)
    declare @Employees table ( lEmployeeID int, sfirstname varchar(max),sDept varchar(max))
    declare @getDate date
    set @getDate ='02/12/2013' 

    insert @Employees 
    values (1,'Ana','1')
    ,(2,'Pedro','1')
    ,(3,'Alfred','2')

    insert @TimeClock
    values (1 ,'02/12/2013 08:30','02/11/2013 11:30')
    ,(2 ,'02/12/2013 08:00','02/11/2013 11:00')
    ,(3 ,'02/12/2013 08:15','02/11/2013 11:15')

您的查询...

    SELECT * FROM (
        SELECT timeclock.dtTimeIn, timeclock.dtTimeOut, employees.sfirstname,
           RANK() OVER (partition by sDept  ORDER BY dtTimeIn) rk1, --earliest record gets 1
           RANK() OVER (partition by sDept  ORDER BY dtTimeOut DESC) rk2 --latest record gets 1

        FROM   @TimeClock timeclock
        INNER JOIN @Employees Employees
        ON TimeClock.lEmployeeID = Employees.lEmployeeID
        WHERE (dtTimeIn > dateadd(day, datediff(day, 0, @getDate)-1, 0)) AND (dtTimeOut < dateadd(day, datediff(day, 0, @getDate), 0)) AND 
          (sDept IN ('1', '2', '3'))
    ) A
    WHERE rk2=1 

...返回

    dtTimeIn            dtTimeOut                   sfirstname  rk1 rk2
    2013-02-12 08:30:00.000 2013-02-11 11:30:00.000 Ana         3   1

请参阅..关闭的是谁在结果集

更改where子句......

SELECT * FROM (
        SELECT timeclock.dtTimeIn, timeclock.dtTimeOut, employees.sfirstname,
           RANK() OVER ( ORDER BY dtTimeIn) rk1, --earliest record gets 1
           RANK() OVER (ORDER BY dtTimeOut DESC) rk2 --latest record gets 1

        FROM   @TimeClock timeclock
        INNER JOIN @Employees Employees
        ON TimeClock.lEmployeeID = Employees.lEmployeeID
        WHERE (dtTimeIn > dateadd(day, datediff(day, 0, @getDate)-1, 0)) AND (dtTimeOut < dateadd(day, datediff(day, 0, @getDate), 0)) AND 
          (sDept IN ('1', '2', '3'))
    ) A
    WHERE rk2=1 
    or rk1 = 1

返回...谁打开谁关闭...

        dtTimeIn            dtTimeOut               sfirstname  rk1 rk2
    2013-02-12 08:30:00.000 2013-02-11 11:30:00.000 Ana     3   1

    2013-02-12 08:00:00.000 2013-02-11 11:00:00.000 Pedro   1   3
2013-02-12 08:15:00.000 2013-02-11 11:15:00.000 Alfred  1   1

Pedro确实打开了,Ana关闭了sDept'1'并且Alfred确实打开并关闭了sDept'2'