2

我有一个查询,它从一个部门中第一个打卡的人,以及从一个部门最后一个打卡的人。本质上,这向我显示了谁打开了一个位置,并关闭了一个位置。下面是我的查询我正在使用“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 
4

3 回答 3

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).

于 2013-02-12T18:45:19.023 回答
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')
于 2013-02-12T19:34:46.173 回答
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'

于 2013-02-12T19:16:43.543 回答