1

有人可以帮我完成下一个任务吗?这里有一个问题:我们有一个历史记录表(记录的状态变化),我们需要计算记录处于特定状态的时间(以天为单位)。这是历史表的结构:

ID| RecordId| CreatedDate         | Field  | OldValue      | NewValue
1 | Record1 | 2013-08-07 09:40:31 | Status | Open          | Awaiting Info
2 | Record1 | 2013-08-08 07:30:20 | Status | Awaiting Info | Open
3 | Record1 | 2013-08-14 01:45:42 | Status | Open          | Resolved

因此,我们需要创建如下表:

Status   | TimeSpentInStatusInDays
Open     |     2
Awaiting |     3
Resolved |     1

例如值(它们与实际数据集没有连接),但结构完全相同,我们需要跟踪四种不同的状态。

任何帮助将不胜感激。谢谢。

4

2 回答 2

1

你需要得到下一个日期,然后拿差价。MySQL没有这个lead()功能,可以使用关联子查询。结果是这样的:

select h.status,
       sum(datediff(nextCreatedDate, CreatedDate)) as TotalDays
from (select h.*,
             (select h2.CreatedDate
              from history h2
              where h2.CreatedDate > h.CreatedDate and
                    h2.RecordID = h.RecordId
              order by h2.CreatedDate
              limit 1
             ) as nextCreatedDate
      from history h
     ) h
group by h.status;

这也将具有不错的性能,索引为history(RecordId, CreatedDate).

编辑:

另一种方法是使用变量:

select h.status,
       sum(datediff(nextCreatedDate, CreatedDate)) as TotalDays
from (select h.*, @nextDate as nextCreatedDate,
             @nextdate := if(@RecordId = @nextRecordId, CreatedDate, NULL),
             @nextRecordId := RecordId,
      from history h cross join
           (select @nextdate := NULL, @nextRecordId := NULL) const
      order by RecordId, CreatedDate desc
     ) h
group by h.status;

我不太喜欢这种方法,因为它取决于子查询中带有变量的参数的估值顺序。MySQL 不保证排序。

于 2013-08-31T13:06:00.503 回答
0

您可以使用 datediff 函数。它返回天数的差异。假设您必须计算记录 id 1 处于打开状态时的天数,查询将是:

select DateDiff((select Created_Date from histtable where RecordId='1' and   
Status='Awaiting'), (select Created_Date from histtable where RecordId='1' and 
Status='Open')); 

Awaiting 是紧随 Open 状态之后的下一个状态,因此从 Open 状态日期中减去它会计算出一条记录处于 Open 状态的天数。

同样,如果您使用某种公式,您可以获得特定记录的不同状态的天数。

如果我清楚地理解您的问题,则记录解决所需的天数 =(解决日期 - 打开日期)。

于 2013-08-31T14:14:06.120 回答