显示现有活动的预计事件列表

时间:2017-12-08 01:43:19

标签: sql sql-server

我想的越多,看起来就越复杂,但我想要的是基于正在进行的工作的工作量计划报告。随着作业的进行,将一行添加到数据库(我的控件之外)中,并使用最后一个事件的日期。事件按顺序发生,每个事件都有一个应该进行活动的时间范围。

下面的示例表和数据:

CREATE TABLE [dbo].[Customers](
    [Cust_ID] [int] NOT NULL,
    [CustName] [varchar](50) NULL
)
INSERT [dbo].[Customers] ([Cust_ID], [CustName]) VALUES (1, N'ABC Corp')
INSERT [dbo].[Customers] ([Cust_ID], [CustName]) VALUES (2, N'Nuke')
INSERT [dbo].[Customers] ([Cust_ID], [CustName]) VALUES (3, N'ADUDAS')
INSERT [dbo].[Customers] ([Cust_ID], [CustName]) VALUES (4, N'POMA')


CREATE TABLE [dbo].[EventInfo](
    [Event_Name] [varchar](50) NOT NULL,
    [Sequence] [int] NOT NULL,
    [NextEvent] [varchar](50) NOT NULL,
    [NextEventDays] [int] NOT NULL
)
INSERT [dbo].[EventInfo] ([Event_Name], [Sequence], [NextEvent], [NextEventDays]) VALUES (N'Received Request', 1, N'Draft Proposal', 5)
INSERT [dbo].[EventInfo] ([Event_Name], [Sequence], [NextEvent], [NextEventDays]) VALUES (N'Draft Proposal', 2, N'Proposal Accepted', 14)
INSERT [dbo].[EventInfo] ([Event_Name], [Sequence], [NextEvent], [NextEventDays]) VALUES (N'Proposal Accepted', 3, N'Project Scheduled', 14)
INSERT [dbo].[EventInfo] ([Event_Name], [Sequence], [NextEvent], [NextEventDays]) VALUES (N'Project Scheduled', 4, N'Project Start', 5)
INSERT [dbo].[EventInfo] ([Event_Name], [Sequence], [NextEvent], [NextEventDays]) VALUES (N'Project Start', 5, N'Project Complete', 30)
INSERT [dbo].[EventInfo] ([Event_Name], [Sequence], [NextEvent], [NextEventDays]) VALUES (N'Project Complete', 6, N'Output Accepted', 14)
INSERT [dbo].[EventInfo] ([Event_Name], [Sequence], [NextEvent], [NextEventDays]) VALUES (N'Proposal Rejected', 3, N'Draft Proposal', 5)
INSERT [dbo].[EventInfo] ([Event_Name], [Sequence], [NextEvent], [NextEventDays]) VALUES (N'Output Rejected', 6, N'Project Start', 5)
INSERT [dbo].[EventInfo] ([Event_Name], [Sequence], [NextEvent], [NextEventDays]) VALUES (N'Output Accepted', 7, N'Complete', 0)


CREATE TABLE [dbo].[Events](
    [Cust_ID] [int] NOT NULL,
    [EventName] [varchar](50) NOT NULL,
    [EventDate] [datetime] NOT NULL
)
INSERT [dbo].[Events] ([Cust_ID], [EventName], [EventDate]) VALUES (1, N'Received Request', CAST(N'2017-10-01T00:00:00.000' AS DateTime))
INSERT [dbo].[Events] ([Cust_ID], [EventName], [EventDate]) VALUES (1, N'Draft Proposal', CAST(N'2017-10-03T00:00:00.000' AS DateTime))
INSERT [dbo].[Events] ([Cust_ID], [EventName], [EventDate]) VALUES (1, N'Proposal Accepted', CAST(N'2017-10-23T00:00:00.000' AS DateTime))
INSERT [dbo].[Events] ([Cust_ID], [EventName], [EventDate]) VALUES (1, N'Project Scheduled', CAST(N'2017-10-23T00:00:00.000' AS DateTime))
INSERT [dbo].[Events] ([Cust_ID], [EventName], [EventDate]) VALUES (1, N'Project Start', CAST(N'2017-10-25T00:00:00.000' AS DateTime))
INSERT [dbo].[Events] ([Cust_ID], [EventName], [EventDate]) VALUES (2, N'Received Request', CAST(N'2017-10-11T00:00:00.000' AS DateTime))
INSERT [dbo].[Events] ([Cust_ID], [EventName], [EventDate]) VALUES (1, N'Project Complete', CAST(N'2017-11-05T00:00:00.000' AS DateTime))
INSERT [dbo].[Events] ([Cust_ID], [EventName], [EventDate]) VALUES (1, N'Output Accepted', CAST(N'2017-11-07T00:00:00.000' AS DateTime))
INSERT [dbo].[Events] ([Cust_ID], [EventName], [EventDate]) VALUES (2, N'Draft Proposal', CAST(N'2017-10-15T00:00:00.000' AS DateTime))

我可以轻松搞定实际事件。

+---------+----------+-------------------+-------------------------+----------+-------------------+---------------+-------------------------+
| Cust_ID | CustName |     EventName     |        EventDate        | Sequence |     NextEvent     | NextEventDays |        NextEvent        |
+---------+----------+-------------------+-------------------------+----------+-------------------+---------------+-------------------------+
|       1 | ABC Corp | Received Request  | 2017-10-01 00:00:00.000 |        1 | Draft Proposal    |             5 | 2017-10-06 00:00:00.000 |
|       1 | ABC Corp | Draft Proposal    | 2017-10-03 00:00:00.000 |        2 | Proposal Accepted |            14 | 2017-10-17 00:00:00.000 |
|       1 | ABC Corp | Proposal Accepted | 2017-10-23 00:00:00.000 |        3 | Project Scheduled |            14 | 2017-11-06 00:00:00.000 |
|       1 | ABC Corp | Project Scheduled | 2017-10-23 00:00:00.000 |        4 | Project Start     |             5 | 2017-10-28 00:00:00.000 |
|       1 | ABC Corp | Project Start     | 2017-10-25 00:00:00.000 |        5 | Project Complete  |            30 | 2017-11-24 00:00:00.000 |
|       1 | ABC Corp | Project Complete  | 2017-11-05 00:00:00.000 |        6 | Output Accepted   |            14 | 2017-11-19 00:00:00.000 |
|       1 | ABC Corp | Output Accepted   | 2017-11-07 00:00:00.000 |        7 | Complete          |             0 | 2017-11-07 00:00:00.000 |
|       2 | Nuke     | Received Request  | 2017-10-11 00:00:00.000 |        1 | Draft Proposal    |             5 | 2017-10-16 00:00:00.000 |
|       2 | Nuke     | Draft Proposal    | 2017-10-15 00:00:00.000 |        2 | Proposal Accepted |            14 | 2017-10-29 00:00:00.000 |
+---------+----------+-------------------+-------------------------+----------+-------------------+---------------+-------------------------+

...使用此查询:

SELECT        Customers.Cust_ID, Customers.CustName, Events.EventName, Events.EventDate, EventInfo.Sequence, EventInfo.NextEvent, EventInfo.NextEventDays, Events.EventDate + EventInfo.NextEventDays AS NextEvent
FROM            Events INNER JOIN
                         EventInfo ON Events.EventName = EventInfo.Event_Name INNER JOIN
                         Customers ON Events.Cust_ID = Customers.Cust_ID
ORDER BY Customers.Cust_ID, EventInfo.Sequence

但我真正追求的(使用可用数据)更像是这样:

+---------+----------+-------------------+------------+-------------+
| Cust_ID | CustName |     EventName     | EventDate  | IsEstimated |
+---------+----------+-------------------+------------+-------------+
|       1 | ABC Corp | Received Request  | 1/10/2017  |           0 |
|       1 | ABC Corp | Draft Proposal    | 3/10/2017  |           0 |
|       1 | ABC Corp | Proposal Accepted | 23/10/2017 |           0 |
|       1 | ABC Corp | Project Scheduled | 23/10/2017 |           0 |
|       1 | ABC Corp | Project Start     | 25/10/2017 |           0 |
|       1 | ABC Corp | Project Complete  | 5/11/2017  |           0 |
|       1 | ABC Corp | Output Accepted   | 7/11/2017  |           0 |
|       1 | ABC Corp | Complete          | 7/11/2017  |           0 |
|       2 | Nuke     | Received Request  | 11/10/2017 |           0 |
|       2 | Nuke     | Draft Proposal    | 15/10/2017 |           0 |
|       2 | Nuke     | Proposal Accepted | 29/10/2017 |           1 |
|       2 | Nuke     | Project Scheduled | 12/11/2017 |           1 |
|       2 | Nuke     | Project Start     | 17/11/2017 |           1 |
|       2 | Nuke     | Project Complete  | 17/12/2017 |           1 |
|       2 | Nuke     | Output Accepted   | 22/12/2017 |           1 |
|       2 | Nuke     | Complete          | 22/12/2017 |           1 |
+---------+----------+-------------------+------------+-------------+

我们的想法是,我们可以选择一个日期范围,看看在此期间发生/将要发生的事情。因此,每个作业每个阶段都会有一行,直至完成,并带有一个标记,用于标识所显示的日期是真实的还是预测的。

在上表中,根据我的示例查询,从Events表中提取了'IsEstimated'= 0的行。具有'IsEstimated'的行已根据该客户的上一个实际事件加上[EventInfo]的值[extEventDays]计算。

这可能更清楚:

+---------+-------------------+------------+-----------+------------+
| Cust_ID |     EventName     |  RealDate  | EventDays |  EstDate   |
+---------+-------------------+------------+-----------+------------+
|       2 | Received Request  | 11/10/2017 |           |            |
|       2 | Draft Proposal    | 15/10/2017 | 5.00      |            |
|       2 | Proposal Accepted |            | 14.00     | 29/10/2017 |
|       2 | Project Scheduled |            | 14.00     | 12/11/2017 |
|       2 | Project Start     |            | 5.00      | 17/11/2017 |
|       2 | Project Complete  |            | 30.00     | 17/12/2017 |
|       2 | Output Accepted   |            | 14.00     | 22/12/2017 |
|       2 | Complete          |            | 0.00      | 22/12/2017 |
|      45 |                   |            |           |            |
+---------+-------------------+------------+-----------+------------+

我正在尝试提取真实的事件记录,并根据每个事件的“NextEventDays”,为尚未存在的事件添加行,以及所有先前事件的累积日期。

我还应该注意,我确实控制了'EventInfo'表的结构和内容,并且我认为更新到中间表的存储过程可能更合适(我使用这些数据进行SSRS报告)。

非常感谢任何有关如何取得进展的想法。

由于

编辑:SQL Fiddle有多棒?

1 个答案:

答案 0 :(得分:1)

您需要做的是使用您需要的数据创建临时表(或表变量,无论如何),然后填充它并从中进行报告。我会做类似

的事情
  1. 使用Cust_ID,EventName,EventDate创建临时表, IsEstimated
  2. 使用您已有的查询填写此内容 实际数据(将这些行的IsEstimated设置为0)
  3. 使用IsEstimated as yes
  4. 创建未来估算值(见下文)
  5. 此表中的报告
  6. 要创建估计数据,您需要找到丢失的行,并确定它们应具有的日期。你可以在一个查询中做一些思考,但是分两步完成它更容易理解

    要获取缺失的行,您需要一个包含所有缺失事件的列表。您需要找出一种方法来指定哪些事件是必不可少的 - 如果可能的话,我会在eventinfo表中添加另一个列,称为BestPath,并将其设置为1,作为理想路径的事件。此时您可以忽略所有其他人。将事件信息与Customers表交叉连接,可以获得在理想路径上应采取的所有步骤的列表。

    但是,您已经完成了其中的一些工作。你不能说不做任何已经存在的事情,因为你可能已经回来并需要做两次,所以你需要为每个客户获得最新的有效SeqenceNo,然后为每个客户获取序列号后面的最佳路径上的所有步骤,并将它们插入临时表中。假设你的临时表是#FullData,你需要这样的东西

    --Get the future rows
    With EventBase as (
        Select E.Cust_ID, EI.Sequence, E.EventDate, ROW_NUMBER () over (PARTITION BY E.Cust_ID  ORDER BY E.EventDate DESC) as RowNo
        From [Events] E
            INNER JOIN EventInfo EI on EI.Event_Name = E.EventName
    ), LastKnownEvent as 
    (
        SELECT Cust_ID, Sequence as LastSequence, EventDate
        FROM EventBase 
        WHERE RowNo = 1
    ), AllEvents as
    (
        SELECT EI.Event_Name, EI.Sequence, EI.NextEventDays, LE.Cust_ID, LE.LastSequence, LE.EventDate
        FROM EventInfo EI
            CROSS JOIN LastKnownEvent LE
        WHERE EI.BestPath = 1
    )
    INSERT INTO #FullData (Cust_ID, Event_Name, Sequence, IsEstimated, LastKnownDate)
    SELECT Cust_ID, Event_Name, Sequence, 1, EventDate
    FROM AllEvents AE
    WHERE Sequence > LastSequence;
    

    获得该数据后,处理临时表并计算每个未来行所需的日期(获取具有较低序列号的同一客户的所有未来行的所有NextEventDays的总和,以及上一个已知的nexteventdays event,然后dateadd到LastknownDate),并将其存储在临时表中。

    此时,临时表应包含报告所需的所有数据。