简体   繁体   English

SQL Server在不同行之间查找datediff

[英]SQL Server find datediff between different rows

I am trying to build a query that analyzes data in our time tracking system. 我正在尝试建立一个查询,以分析我们的时间跟踪系统中的数据。 Every time a user punches in or out, it makes a row recording the punch time. 每次用户进出时,它都会记录一次打卡时间。 So if you punch in at 9:00 and punch out at 5:00 there are two rows with those date stamps recorded accordingly. 因此,如果您在9:00打孔,在5:00打孔,则会有两行记录相应的日期戳。 I need a query that will iterate over the rows at basically sum the datediff between workingpunch_ts (the timestamp column) in hours. 我需要一个查询,它将对行进行迭代,基本上以小时为单位计算workingpunch_ts (时间戳列)之间的datediff workingpunch_ts和。

Each row does have an identifier that signifies if the punch is a punch in, or punch out ( inout_id , 1 for in, 2 for out). 每行都具有一个标识符,用于指示该打孔器是打孔器还是打孔器( inout_id ,1表示in,2表示out)。

So for example if you had 例如,如果您有

ID  | workingpunch_ts         | inout_id
----------------------------------------------
123 | 2011-02-16 09:00:00.000 | 1
124 | 2011-02-16 17:00:00.000 | 2

That would yield a 8 hours. 这将产生一个8个小时。 Now I just need to repeat that process for every pair of rows in the table. 现在,我只需要对表中的每一对行重复该过程。

Thoughts on how to accomplish this? 关于如何做到这一点的想法?

This query will give you problems if people punch in and out multiple times on the same day: 如果人们在同一天多次进出,此查询将给您带来问题:

Table schema: 表架构:

CREATE TABLE [dbo].[TimePunch](
    [TimeCardID] [int] IDENTITY(1,1) NOT NULL,
    [PunchTime] [datetime] NOT NULL,
    [InOrOut] [int] NOT NULL,
    [UserID] [int] NOT NULL,
    [DayofPunch] [datetime] NOT NULL,
 CONSTRAINT [PK_TimePunch] PRIMARY KEY CLUSTERED 
(
    [TimeCardID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 10) ON [PRIMARY]
) ON [PRIMARY]

Query: 查询:

select 
    tIn.UserID,
    tIn.DayOfPunch,
    DateDiff(Hour, tIn.PunchTime, tOut.PunchTime) as HoursWorked
FROM
    TimePunch tIn,
    TimePunch tOut
WHERE
    tIn.InOrOut = 1
AND tOut.InOrOut = 2
AND tIn.UserID = tOut.UserID
AND tIn.DayofPunch = tOut.DayOfPunch

In hours, sure 在几个小时内

select empid, cast(datediff(d,0,workingpunch_ts) as datetime),
    SUM(case when inout_id = 2 then 1 else -1 end *
    datediff(MI, datediff(d,0,workingpunch_ts), workingpunch_ts))/60.0 as Hours
from clock
where workingpunch_ts between '20110201' and '20110228 23:59:59.999'
group by empid, datediff(d,0,workingpunch_ts)

As long as the in and outs are paired, you add all the outs and remove all the ins, eg 只要输入输出配对,就可以添加所有输出并删除所有输入,例如

 - IN  (9)
 + OUT (12)
 - IN  (13:15)
 + OUT (17)

The main code is in the 2nd and 3rd lines 主要代码在第二和第三行
The datediff-datediff works out the minutes from midnight for each workingpunch_ts , and if it is a punchout, it is made negative using the CASE inout_id statement. datediff-datediff计算出每个workingpunch_ts从午夜开始的分钟,如果是inout_id ,则使用CASE inout_id语句将其设置为负数。

The others are added for real life scenarios where you need to group by employee and day, within a date range. 在现实生活中添加了其他选项,其中您需要在日期范围内按员工和日期分组。

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

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