如何从历史表中选择天数?

时间:2015-03-01 07:31:27

标签: sql sql-server sql-server-2008


已编辑:历史记录表可能包含在时间计算中无效的行(例如评论或发送提醒......)

我有2个具有以下结构的表

PS:为了简单起见,我避免涉及太多细节(实际上,我有另一个用于STATUS代码的表,另一个用于用户等等)。


门票表

--------------------------------------------------
| ID  | Ticket_Details   | Issued_By | Status    |
--------------------------------------------------
| 001 | 'PC not working' | 'John'    | On Hold   |
| 002 | 'Printer broken' | 'Mike'    | Rejected  |
| 003 | 'Network down'   | 'Alex'    | Submitted |
| ..  | ...              | ..        | ...       |
--------------------------------------------------

历史表

------------------------------------------------------------------------
| ID | Ticket_ID  | Ticket_Status | History_Details      | Insert_Date |
------------------------------------------------------------------------
| 01 | 001        | new           | submitted            | 23-Feb-2015 |
| 02 | 001        | submitted     | assigned to [Frank]  | 25-Feb-2015 |
| 03 | 001        | submitted     | commented 'needs ti.'| 25-Feb-2015 |
| 04 | 001        | assigned      | put on hold by[Frank]| 26-Feb-2015 |
| 05 | 001        | on hold       | reminder sent        | 01-Mar-2015 |
| 06 | 002        | new           | submitted            | 23-Feb-2015 |
| 07 | 002        | submitted     | rejected by [Sam]    | 24-Feb-2015 |
| 08 | 003        | new           | submitted            | 25-Feb-2015 |
------------------------------------------------------------------------

历史记录表的每一行都包含以下信息:

1- id(auto inc)主键

2-票证ID的外键

3-修改故障单之前的状态

对票证采取了什么行动的4-评论

5-行动的日期[和时间]

请注意,有些行描述了状态的变化,而有些行则没有变化。只有评论或提醒被发送,而票证保持其状态。

现在我想要实现的是一个表格,它显示了故障单的当前状态以及分配给此状态的天数。因此,对于上面的示例数据,输出应为:(考虑今天的日期是2015年3月1日)


期望的输出

--------------------------------------------------
| ID  | Ticket_Details   | Status    | Since     |
--------------------------------------------------
| 001 | 'PC not working' | On Hold   | 3 days    |
| 002 | 'Printer broken' | Rejeced   | 5 days    |
| 003 | 'Network down'   | submitted | 4 days    |
| ..  | ...              | ..        |           |
--------------------------------------------------

基本上,我使用insert_date表中history中存储的信息来确定故障单处于该状态的时间。

以下是我的尝试:

select 
   t.id,
   t.ticket_details,
   t.status,
   datediff(day, h.insert_date, getdate() ) "since"
from
         tickets t 
   left join history h on t.id = h.ticket_id
             and h.id = ( select max(id) from history h2 
                          where h2.ticket_id = h.ticket_id 
                                AND h2.ticket_status = t.status )

我告诉SQL在history中查找最后一次此票证有status的内容。

但由于部分"since"值出现nulls,我获得了准确的数据。

我做错了什么?

2 个答案:

答案 0 :(得分:1)

也许试试

select 
   t.id,
   t.ticket_details,
   t.status,
   datediff(day, h.insert_date, getdate() ) "since"
from
         tickets t 
   left join (SELECT MAX(insert_date) as insert_date,ticket_id
               FROM history group by ticket_id) as h 
              on t.id=h.ticket_id

答案 1 :(得分:1)

我认为这是对cross apply

的好用
select t.*, datediff(day, minid, getdate()) as days_since
from tickets t outer apply
     (select min(insert_date) as minid
      from history h
      where h.ticket_id = t.ticket_id and h.ticket_status = t.status
     ) h;

注意:这将返回故障单处于当前状态的最早日期。这假设票证永远不会返回到先前的状态,这与您问题中的信息一致。