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

これで試すことができます:

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 に答える
2

相関サブクエリに置き換えることができます。の例を次に示しrk1ます。

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

ランクは、すべて 1 でラベル付けされた複数のレコードを生成できます (同点の場合)。本当に を意味する場合は、上記のクエリで の代わりに をrow_number()使用します。count(*)count(distinct)

于 2013-02-12T18:45:19.023 に答える
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 が sDept '1' を開き、Ana が閉じ、Alfred が sDept '2' を開き、閉じました。

于 2013-02-12T19:16:43.543 に答える