C# 计算不同行和不同列的持续时间?

C# 计算不同行和不同列的持续时间?,c#,sql,asp.net,sql-server,C#,Sql,Asp.net,Sql Server,我想计算不同行和不同列中的持续时间。这是我的示例数据: 'STATUSIN'(在第二行)-'STATUSOUT'(在第一行)我想把输出放在'LOSTTIME'列中 例如: 08:07:53 - 08:06:22 = 00:01:31 (OUTPUT) 这是我显示数据库数据的代码: <asp:Repeater ID="rptrDAILYDATAWH" runat="server"> <HeaderTemplate>

我想计算不同行和不同列中的持续时间。这是我的示例数据:

'STATUSIN'(在第二行)-'STATUSOUT'(在第一行)
我想把输出放在'LOSTTIME'列中

例如:

08:07:53 - 08:06:22  = 00:01:31 (OUTPUT)
这是我显示数据库数据的代码:

<asp:Repeater ID="rptrDAILYDATAWH" runat="server">
            <HeaderTemplate>
                <table class="table">
                    <thead>
                        <tr>
                            <th>NIP</th>
                            <th>NAME</th>
                            <th>DEPARTMENT</th>
                            <th>IN</th>
                            <th>OUT</th>
                            <th>LOSTTIME</th>
                       </tr>
                    </thead>
                    <tbody>
            </HeaderTemplate>
            <ItemTemplate>
                <tr>
                    <th><%# Eval("NIP") %></th>
                    <td><%# Eval("NAME") %></td>
                    <td><%# Eval("DEPARTMENT") %></td>
                    <td><%# Eval("STATUSIN") %></td>
                    <td><%# Eval("STATUSOUT") %></td>
                    <td><%# Eval("LOSTTIME") %></td>
                </tr>
            </ItemTemplate>
            <FooterTemplate>
                    </tbody>
                </table>
            </FooterTemplate>
        </asp:Repeater>

您基本上需要的是
LAG
。请阅读本文以了解更多信息。这适用于SQL Server 2012及以后的版本。在中获得prev状态后,可以在运行时在
C#

SQL Server 2008的另一个解决方案是使用自连接

SELECT a.NIP, a.NAME, a.DEPARTMENT, a.STATUSIN, a.STATUSOUT, 
       CONVERT(VARCHAR, CONVERT(TIME, b.STATUSIN  - a.STATUSOUT), 108) LOSTTIME
FROM DAILYDATAWH a 
  LEFT JOIN DAILYDATAWH b ON a.ID = b.ID - 1 AND a.NIP = b.NIP AND a.NAME = b.NAME AND a.DEPARTMENT = b.DEPARTMENT
输出

要更新
LOSTTIME
,您应该执行以下操作

UPDATE a SET a.LOSTTIME = CONVERT(TIME, b.STATUSIN  - a.STATUSOUT)
FROM DAILYDATAWH a 
  LEFT JOIN DAILYDATAWH b ON a.ID = b.ID - 1 AND a.NIP = b.NIP AND a.NAME = b.NAME AND a.DEPARTMENT = b.DEPARTMENT

由于数据中没有
LOSTTIME
,因此可以在中继器中计算:

更改:

<td><%# Eval("LOSTTIME") %></td>

Convert.ToDateTime(Eval(“STATUSIN”))?Convert.ToDateTime(Eval(“STATUSOUT”)).Subtract(Convert.ToDateTime(Eval(“STATUSIN”)).ToString():“-”%>

如果您使用的是SQL Server,您可以根据需要参考下面的脚本

选择DATEADD(DAY,-1,GETDATE())作为“第一个日期”,选择GETDATE()作为“第二个日期”,
格式(DATEADD(ss,DATEDIFF(ss,'2020-02-10 10:30:00.143','2020-02-11 14:22:20.683'),0),'hh:mm:ss')为“差异”

如果作为一般规则,使用
选择*
,而不是指定列名,会发生什么。如果您重新排序/重命名/删除列,这将有助于避免错误,因为这样您的查询将中断,您会注意到您需要更早地更改代码。对不起,我已更正了我的问题如果一个用户在给定的一天有三种状态怎么办?@SalmanA此数据只显示一天,因此数据将被过滤一天。谢谢,但是还有一个不使用滞后的选项吗?因为我使用的是sql server 2008,而LAG函数刚刚在sql server 2012中起作用,所以我不确定此解决方案是否解决了上述问题。@deananda
LAG()
(及其对应的
LEAD()
)是
JOIN
的语法糖。您可以使用ID中的偏移量将表连接到自身,以实现相同的目标。@Deananda,我已使用
自连接添加了另一个解决方案,以获取以前的记录。希望如此helps@TsahiAsher是的,你是对的。获取以前的记录在这里是一个挑战,一旦您获得以前的值,添加if条件将更容易。谢谢,很抱歉我已经更正了我的问题。我想将输出放在“LOSTTIME”列中。您不需要
,您可以在repeater
Convert.ToDateTime(Eval(“STATUSIN”))中执行此操作?Convert.ToDateTime(Eval(“STATUSOUT”))。Subtract(Convert.ToDateTime(Eval(“STATUSIN”)))。ToString():“-”%>
对您不起作用?谢谢,它起作用了。但是,我指的不是输出。请再次检查我的问题并查看示例数据,例如:
08:07:53-08:06:22=00:01:31(输出)
。这是计算不同的列和不同的行我不是指在同一行中计算,我是指在不同的行中计算,请再次检查有问题的图像中的样本数据。计算
'STATUSIN'(第二行)-'STATUSOUT'(第一行)
谢谢您的帮助,但我指的不是输出
UPDATE a SET a.LOSTTIME = CONVERT(TIME, b.STATUSIN  - a.STATUSOUT)
FROM DAILYDATAWH a 
  LEFT JOIN DAILYDATAWH b ON a.ID = b.ID - 1 AND a.NIP = b.NIP AND a.NAME = b.NAME AND a.DEPARTMENT = b.DEPARTMENT
<td><%# Eval("LOSTTIME") %></td>
<%# Convert.ToDateTime(Eval("STATUSOUT")) > Convert.ToDateTime(Eval("STATUSIN")) ? Convert.ToDateTime(Eval("STATUSOUT")).Subtract(Convert.ToDateTime(Eval("STATUSIN"))).ToString() : "-" %>