C# 如何计算同一张桌子上不同线路上的时间差

C# 如何计算同一张桌子上不同线路上的时间差,c#,sql,database,C#,Sql,Database,我想知道如果数据在同一个表中,但在两个单独的行上,如何获得时间差。例如,下面我有一个数据截图,每个员工都有两条记录,第一个时钟点和最后一个时钟点。我想要这些时间之间的差异,并将其保存到一个新表中。我该怎么做 表结构: CREATE TABLE [dbo].[RefinedData]( [ClockNo] [nvarchar](50) NULL, [FirstName] [nvarchar](50) NULL, [LastName] [nvarchar](50) NULL, [Department

我想知道如果数据在同一个表中,但在两个单独的行上,如何获得时间差。例如,下面我有一个数据截图,每个员工都有两条记录,第一个时钟点和最后一个时钟点。我想要这些时间之间的差异,并将其保存到一个新表中。我该怎么做

表结构:

CREATE TABLE [dbo].[RefinedData](
[ClockNo] [nvarchar](50) NULL,
[FirstName] [nvarchar](50) NULL,
[LastName] [nvarchar](50) NULL,
[Department] [nvarchar](50) NULL,
[ClockPoint] [nvarchar](50) NULL,
[Date] [nvarchar](50) NULL,
[Time] [int] NULL
) ON [PRIMARY]
数据布局:


因此,在本例中,我希望将用户Gerard的时差保存在一个新表中,但每个用户只能保存一条记录。

您可以执行以下操作:

var differences = 
    refinedData.GroupBy(d => d.ClockNo)
               .Select( g => g.OrderBy(d => d.Time))
               .Select( g => new {
                   ClockNo = g.ClockNo,
                   Difference = g.Last() - g.First() });
试试这个-

select Firstname,cast(max(Time)-min(Time) as time) as 'time difference'
into #temptable
from RefinedData 
where FirstName like 'Gerard'
and Date like '20180301'
group by Firstname

从示例数据可以明显看出,每个用户有2行数据。
行号
适用于您。减去rn2-rn1将返回所需的输出

with cte as
(select  [ClockNo] ,
        [FirstName] ,
        [LastName] ,
        [Department] ,
        [ClockPoint] ,
        [Date] ,
        time,
        ROW_NUMBER() over partition by clockno,firstname order by date,time) rn
        from mytable 
        ) 

        select  c.[ClockNo] ,
        c.[FirstName] ,
        c.[LastName] ,
        c.[Department] ,
        c.[ClockPoint] ,
        c.[Date] ,
        c1.time -c.time
        from cte c inner join (select * from  cte where rn= 2) c1 
        on c.rn = c1.rn-1 and c.firstname = c.firstname and c.clockno = c1.cloclno 
         where c.rn = 1

您可以从以下内容开始:

select *, datediff(hour, LAG([Datetime]) over (partition by FirstName, LastName order by [Datetime]), [Datetime]) [Difference_in_hours]
from (
select FirstName,
       LastName,
       ClockPoint,
       --get correctly formatted date column
       cast(stuff(STUFF([DATE], len([DATE]) - 3, 0, '-'), len([DATE]), 0, '-') + ' ' + stuff(STUFF([time], len([time]) - 3, 0, ':'), len([time]), 0, ':') as datetime) [Datetime]
from [RefinedData]
) a where
ClockPoint like '% out %' or
ClockPoint like '% in %' or
ClockPoint like '% out' or
ClockPoint like '% in' or
ClockPoint like 'out %' or
ClockPoint like 'in %'


您确定总是有两个用户签入/签出条目请提供要插入的测试数据时钟#93是什么?两次不离开就进来了?您的表缺少重要信息,目前只能通过文本解析来建立这些信息。此外,我强烈建议对表进行规范化,并添加正确的主键。您公司的员工(很容易找到)是怎么做的你觉得你发布了关于他们的非匿名信息吗?这里没有提到LINQ。@spender但它提到了c#。我发现很难想象在当前上下文中,除了linq之外,c#标记还能包含什么。@在这两者之间,我看到标记“sql”确定当它们多次进出时,会发生什么?现在它将从特定日期的最大时间中减去最小时间,所以现在它们在同一天进出两次。。。现在怎么办?…或者他们在午夜前进入,午夜后离开?这是一个奶牛场,所以这不太可能。所以他将从当天最后一个出口减去最早的入口。入口和出口不保证是连续的,如上面的入口#93所示。这将失败。这个答案是正确的。我会在窗口函数中的order by中添加“Date”列,以确保不计算不同日期之间的时差。时钟点应该在第93条中,可能是输入错误,OP应该confirm@EzequielL奥佩斯干杯。我添加了日期列,以确保行是唯一的。如果员工在午夜之前进入,而在午夜之后离开,该怎么办?假设这种情况永远不会发生,安全吗?再一次,看看条目#93,想想任意选择连续条目的合理性。@spender我不明白。你知道什么?你正在使用LAG从前一行中选择条目。不能保证这对时间会给你一个进入和一个退出(即计时时间跨度)。上面的ClockNo 93说明了这个问题。@spender这些案例中的问题有点不清楚。。。但您是对的,添加了
where
子句以更接近OP的要求。