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

Posted

技术标签:

【中文标题】计算不同行和不同列的持续时间?【英文标题】:Calcuate time duration in different row and different column? 【发布时间】:2020-02-12 07:56:59 【问题描述】:

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

'STATUSIN'(in second row) - 'STATUSOUT'(in first row) 我想将输出放在“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>

这是后端的代码:

protected void BindDAILYDATWHARptr() 
  String CS = ConfigurationManager.ConnectionStrings["MANHOURConnectionString"].ConnectionString;
  using (SqlConnection con = new SqlConnection(CS)) 
    using (SqlCommand cmd = new SqlCommand("SELECT * FROM DAILYDATAWH", con))
      using (SqlDataAdapter sda = new SqlDataAdapter(cmd)) 
        DataTable dtDaily = new DataTable();
        sda.Fill(dtDaily);
        rptrDAILYDATAWH.DataSource = dtDaily;
        rptrDAILYDATAWH.DataBind();
          
    
  
 

【问题讨论】:

如果'STATUSOUT' &lt;= 'STATUSIN' 会发生什么? 作为一般规则,避免使用SELECT *,而是指定列名。如果您重新排序/重命名/删除列,这将有助于避免错误,因为这样您的查询就会中断,您会注意到您需要更早地更改代码。 对不起,我已经纠正了我的问题 如果一个用户在某一天拥有三种状态怎么办? @SalmanA 这个数据只显示了 1 天,所以它的数据被过滤了 1 天。 【参考方案1】:

你基本上需要的是LAG。阅读此article 了解更多信息。这适用于SQL Server 2012 onwards。获得 prev 状态后,您可以在 C#C# 运行时应用所需条件

SELECT NIP, NAME, DEPARTMENT, STATUSIN, STATUSOUT, LAG(STATUSIN,1) OVER(ORDER BY NIP, NAME, DEPARTMENT) PREVSTATUSIN FROM DAILYDATAWH

SQL Server 2008 的另一种解决方案是使用Self JOIN

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

【讨论】:

谢谢您,但是还有另一个不使用 LAG 的选项吗?因为我用的是sql server 2008,而LAG功能只是在sql server 2012中起作用 我不确定这个解决方案是否能解决上述问题。 @DeaAnanda LAG()(及其对应的LEAD())是JOIN 的语法糖。您可以使用 ID 中的偏移量将表连接到自身以实现相同的目标。 @DeaAnanda,我添加了另一个解决方案,使用self join 来获取以前的记录。希望这会有所帮助 @TsahiAsher,是的,你是对的。在这里获取以前的记录是一个挑战,一旦你得到以前的值,添加if条件会更容易。【参考方案2】:

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

SELECT DATEADD(DAY,-1,GETDATE()) AS 'First_date', GETDATE() AS 'Second_date', FORMAT(DATEADD(ss,DATEDIFF(ss,'2020-02-10 10:30:00.143', '2020-02-11 14:22:20.683'),0),'hh:mm:ss') AS'区别'

【讨论】:

谢谢你帮助我,但我的意思不是输出【参考方案3】:

由于您的数据中没有LOSTTIME,您可以在转发器中计算:

变化:

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

<%# Convert.ToDateTime(Eval("STATUSOUT")) > Convert.ToDateTime(Eval("STATUSIN")) ? Convert.ToDateTime(Eval("STATUSOUT")).Subtract(Convert.ToDateTime(Eval("STATUSIN"))).ToString() : "-" %>

【讨论】:

谢谢你,很抱歉我已经更正了我的问题。我想把输出放在“LOSTTIME”列中 你不需要&lt;%# Eval("LOSTTIME") %&gt;,你可以在中继器中这样做&lt;%# Convert.ToDateTime(Eval("STATUSOUT")) &gt; Convert.ToDateTime(Eval("STATUSIN")) ? Convert.ToDateTime(Eval("STATUSOUT")).Subtract(Convert.ToDateTime(Eval("STATUSIN"))).ToString() : "-" %&gt;不适合你? 谢谢,它的工作。但是,这不是我的意思的输出。请再次检查我的问题并查看示例数据,例如:08:07:53 - 08:06:22 = 00:01:31 (OUTPUT)。它计算不同的列和不同的行 我的意思不是在同一行计算,我的意思是在不同的行计算,请再次检查有问题的图像以获取示例数据。计算'STATUSIN'(in second row) - 'STATUSOUT'(in first row)

以上是关于计算不同行和不同列的持续时间?的主要内容,如果未能解决你的问题,请参考以下文章

计算不同行和列的值的差值

使用 Access 计算不同行中不同列中的数字之间的差异

在 SQL 中选择具有 MIN(计算排名)和 GROUPed BY 不同列的行时性能不佳

面对不同行和不同列中的数字

解析文本文件的不同行的有效方法

用于计算不同行状态的分析函数