简体   繁体   English

时钟的相关查询逻辑

[英]Correlated Query Logic for Timeclock

I could really use some help figuring out a query for the following scenario. 我真的可以使用一些帮助来解决以下情况的查询。

tblStaff

| ESID | EID | FName | LName  |
+------+-----+-------+--------+
| 1    | 10  | Joe   | Smith  |
| 2    | 10  | Dan   | Jones  |
| 3    | 10  | Rick  | Brown  |
| 4    | 10  | Pete  | Miller |
| 5    | 10  | Ken   | White  |

tblStaffTime

| TCID | EID | ESID | DTIn                    | DTOut                   |
+------+-----+------+-------------------------+-------------------------+
| 1    | 10  | 1    | 2013-09-22 08:00:00.000 | 2013-09-22 17:00:00.000 |
| 2    | 10  | 1    | 2013-09-23 08:00:00.000 | NULL                    |
| 3    | 10  | 2    | 2013-09-23 08:00:00.000 | 2013-09-23 17:00:00.000 |
| 4    | 10  | 3    | 2013-09-22 08:00:00.000 | 2013-09-22 17:00:00.000 |
| 5    | 10  | 3    | 2013-09-23 08:00:00.000 | NULL                    |

My Objectives are: List all people with EID equal to 10 where the most recent DTOut is not null or they have no record in tblStaffTime at all for this EID. 我的目标是:列出所有EID等于10的人,其中最新的DTOut不为空,或者他们在tblStaffTime中根本没有此EID的记录。 In other words, a list of who is ready to be clocked in for all staff with an EID equal to 10. 换句话说,列出准备好为EID等于10的所有员工挂号的人员。

My SQL so far: 到目前为止,我的SQL:

SELECT tblStaff.ESID AS ID,tblStaff.SFirst + CHAR(32) + tblStaff.SLast AS StaffName
FROM tblStaff
LEFT JOIN tblStaffTime ON tblStaff.ESID = tblStaffTime.ESID
WHERE tblStaff.ESID = (SELECT ESID FROM tblStaffTime WHERE EID = '10' AND ESID = tblStaffTime.ESID AND DTIn IS NOT NULL AND DTOut IS NOT NULL)
UNION ALL
SELECT tblStaff.ESID AS ID,tblStaff.SFirst + CHAR(32) + tblStaff.SLast AS StaffName
FROM tblStaff
LEFT JOIN tblStaffTime ON tblStaff.ESID = tblStaffTime.ESID
WHERE NOT EXISTS (SELECT 1 FROM tblStaffTime WHERE tblStaffTime.ESID = tblStaff.ESID) AND tblStaff.EID = '10'
ORDER BY tblStaff.SFirst + CHAR(32) + tblStaff.SLast

Desired Output: 所需输出:

| ESID | StaffName   |
+------+-------------+
| 2    | Dan Jones   |
| 5    | Ken White   |
| 4    | Pete Miller |

South of my Union solves my issue of getting staff who have not clocked in for this EID. 联盟以南的问题解决了我的问题,即招募尚未为此EID工作的员工。 My major problem is the northern part of my union. 我的主要问题是工会的北部。 I need to get the most recent DTIn and see if DTOut is null or not for that record to determine if they should be listed as ready to clock in. I'm certain this SQL can all be written much cleaner. 我需要获取最新的DTIn并查看该记录的DTOut是否为空,以确定是否应将它们列为准备就绪的时钟。我敢肯定,此SQL都可以写得更加清晰。 I'll leave it to the experts now. 我现在将其交给专家。

If you're using SQL Server 2005 or later, you can use window functions to help with this 如果您使用的是SQL Server 2005或更高版本,则可以使用窗口函数来解决此问题

The left outer join helps include people with no record, and the order by DTIn lets us pick the latest time record when there is one 左外部联接有助于包括无记录的人员,而DTIn的订单使我们可以在有一个记录的情况下选择最新的时间记录

With x as (
    Select
        s.ESID,
        s.EID,
        s.FName,
        s.LName,
        t.DTIn,
        t.DTOut,
        row_number() over (partition by s.ESID, s.EID order by DTIn Desc) rn
    From
        tblStaff s
            Left Outer Join
        tblStaffTime t
            On s.ESID = t.ESID and s.EID = t.EID
)
Select
    x.ESID,
    x.EID,
    x.FName,
    x.LName
From
    x
Where
    x.EID = 10 And
    x.rn = 1 And (
      x.DTIn Is Null Or -- no time records
      x.DTOut IS Not Null -- latest time record has not null clock out
    )

Example Fiddle 小提琴的例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM