如何编写使用先前记录值计算值的查询?

发布于 2024-09-27 07:46:55 字数 1589 浏览 3 评论 0原文

我正在尝试找出计算基于先前记录值的值的最佳方法。我确信这是可能的,我只是无法弄清楚。

考虑一个具有 StartTimeStartTime 的表。 结束时间。除了这些值之外还有 2 种不同类型的工资:OnDuty 和 OnDuty。 下班

OnDuty = StartTimeEndTime 之间的所有时间。

OffDuty上一个 EndTime当前 StartTime 之间的所有时间.

因此,要计算 OffDuty,我们必须采用最后一条记录的 EndTime 并减去当前记录的 StartTime

示例:

  • 上班工资 = $10/小时
  • 下班工资 = $2/小时

条目 1:

StartTime: 1/1/2010 @ 8:00 AM
EndTime: 1/1/2010 @ 6:00 PM
Pay = $100 (10 hrs @ $10/hr)

条目 2:

StartTime: 1/2/2010 @ 8:00 AM
EndTime: 1/2/2010 @ 6:00 PM
Pay = $128 (10 hrs @ $10/hr) + (14 hrs @ $2/hr) 

条目 3:

StartTime: 1/3/2010 @ 8:00 AM
EndTime: 1/3/2010 @ 10:00 AM
Pay = $48 (2 hrs @ $10/hr) + (14 hrs @ $2/hr) 

您看到这个模式了吗?

Total Pay = $276 (Entry1.Pay + Entry2.Pay + Entry3.Pay)

基本上,我正在争论是否最好:

  1. 将所有负担放在数据库上来计算每个详细信息行的该值,或者
  2. 将前一个记录的 EndTime 与每行一起存储(即 PreviousEndTime?)

我喜欢选项1 更好。但是,我什至不知道如何在不先创建查找查询的情况下执行此操作(注意:我使用的是 SqlCE)。我严重依赖 LinqToSql,并且担心使用 Linq 的性能,因为可能需要计算数十万条“条目”记录才能为每个员工提供单个 TotalPay。对每个详细信息行执行查找会很痛苦!

另一方面,我觉得使用“PreviousEndTime”字段方法会涉及大量维护工作。用户可以返回并更改 EndTime,而更新下一个 记录的 PreviousEndTime 的想法对我来说听起来像是黑客……

有什么想法吗?有想法吗?解决方案? :)

I'm trying to figure out the best way to calculate a value that is based on the previous records values. I'm sure it's possible, I just can't figure it out.

Consider a table that has StartTime & EndTime. Along with these values is are 2 different types of wages: OnDuty & OffDuty.

OnDuty = All time between StartTime and EndTime.

OffDuty: All time between the previous EndTime and the current StartTime.

So to calculate OffDuty, we have to take the EndTime of the last record and subtract the StartTime of the current record.

Example:

  • OnDuty Wage = $10/hr
  • OffDuty Wage = $2/hr

Entry 1:

StartTime: 1/1/2010 @ 8:00 AM
EndTime: 1/1/2010 @ 6:00 PM
Pay = $100 (10 hrs @ $10/hr)

Entry 2:

StartTime: 1/2/2010 @ 8:00 AM
EndTime: 1/2/2010 @ 6:00 PM
Pay = $128 (10 hrs @ $10/hr) + (14 hrs @ $2/hr) 

Entry 3:

StartTime: 1/3/2010 @ 8:00 AM
EndTime: 1/3/2010 @ 10:00 AM
Pay = $48 (2 hrs @ $10/hr) + (14 hrs @ $2/hr) 

Do you see the pattern?

Total Pay = $276 (Entry1.Pay + Entry2.Pay + Entry3.Pay)

Basically, I'm debating as to whether it would be best to:

  1. put all of the burden on the database to calculate this value for each detail row, or
  2. store the previous record's EndTime with each row (ie. PreviousEndTime?)

I like option 1 better. However, I don't even know how to approach this in terms of HOW to do this without creating a lookup query first (note: I'm using SqlCE). I'm relying heavily on LinqToSql and I'm concerned with performance using Linq, as there could be hundreds of thousands of these "Entry" records that need calculated to provide a singe TotalPay for each employee. To perform that lookup on each detail row would be painful!

On the flip side, I feel that there would be a lot of maintenance involved with using the 'PreviousEndTime' field approach. The user could go back and change the EndTime and the idea of updating the next record's PreviousEndTime sounds like a hack to me...

Thoughts? Ideas? Solutions? :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

寄风 2024-10-04 07:46:55

我强烈建议选择“将所有负担放在数据库上来计算每个详细信息行的该值”。 这就是数据库(及其查询语言)的用途。

在 Oracle 中,您将使用 LEAD 和 LAG。

http://www.oracle-base.com/articles/misc/LagLeadAnalyticFunctions.php

在 SQL Server 中,可能有一些解决方法,例如:

http://www.rafael-salas.com/2008/05/t-sql-lead-and-lag-functions.html

不确定 SQL 是否支持不过,服务器CE。

I would strongly recommend the option to "put all of the burden on the database to calculate this value for each detail row". This is the stuff databases (and their query languages) are made for.

In Oracle you would use LEAD and LAG.

http://www.oracle-base.com/articles/misc/LagLeadAnalyticFunctions.php

In SQL Server, there may be some workarounds, see for example:

http://www.rafael-salas.com/2008/05/t-sql-lead-and-lag-functions.html

Not sure if this is supported in SQL Server CE, though.

凶凌 2024-10-04 07:46:55

无需存储前一行的结束时间。您可以使用 Row_NUMBER() 排名函数计算与前几行的差异,并然后执行自连接。

There is no need to store the previous row's end time. You can calculate differences with previous rows using the Row_NUMBER() ranking function and then performing a self-join.

鹿港巷口少年归 2024-10-04 07:46:55

答案:为了向大家通报这一点,我采用了不同的方法...

由于我使用的是 SQL CE 并且它不支持视图或超前/滞后函数,因此我决定添加我的表中添加了一个新的 PreviousEndTime 列。这是我能找到的唯一优雅的方式,可以让我轻松查询 Employee 的总计计算。这不是我首选的解决方案,但它对我来说工作正常...

这种方法的唯一缺点是,当用户在任何记录上更新其 EndTime 时,我必须进行快速查找查找下一条记录并更新PreviousEndTime值,以确保我的计算在查询时返回正确的值。

这是我现在正在做的一个快速伪代码片段:

public decimal GetTotalPay(Employee employee) {
   return (from row in _timeSheet.GetDetailRows(employee.Id)
      select ((row.StartTime - row.PreviousEndTime) * employee.OffDutyWage) +
             ((row.EndTime - row.StartTime) * employee.OnDutyWage)).Sum();
}

感谢您的所有反馈。

ANSWER: Just to update everybody on this, I resorted to a different approach...

Since I'm using SQL CE and it doesn't support Views or the Lead / Lag functions, I decided to add a new PreviousEndTime column to my table. This was the only elegant way that I could find that allowed me to easily query for a grand total calculation on an Employee. It is not my preferred solution, but it is working ok for me...

The only draw back with this approach is that when a user updates their EndTime on any record, I have to do a quick lookup to find the next record and update the PreviousEndTime value to ensure that my calculations return the correct values when querying.

Here is a quick pseudo code snippet of what I'm now doing:

public decimal GetTotalPay(Employee employee) {
   return (from row in _timeSheet.GetDetailRows(employee.Id)
      select ((row.StartTime - row.PreviousEndTime) * employee.OffDutyWage) +
             ((row.EndTime - row.StartTime) * employee.OnDutyWage)).Sum();
}

Thanks for all the feedback.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文