0

我有一张包含不同对象的表,并且对象会随着时间的推移而演变。一个对象由object_number标识,我们可以使用object_line_number对其进行跟踪。并且物体的每一次进化都有一个状态。

我想计算某些状态之间经过的时间。

下面是我的一个对象编号“us1”的表:

在此处输入图像描述

黄色是包含开始日期的行。如果 (status_id = 0 和 (old_status <> 0 或 object_line_number = 1) 和 Emergency_level = 1),则可以找到它们。

绿色是包含结束日期的行。如果 (status_id =2,3,4,5 和 old_status = 0),则可以找到它们。

表中不存在列old_status 。这是上一行的状态(根据对象)line_number)。由于以下措施,我正在检索它:

old_status = CALCULATE (
 MAX(fact_object[status_id]),
 FILTER (
        ALL(fact_object), 
        fact_object[object_line_number] = IF(fact_object[object_line_number]=1, fact_object[object_line_number], MAX (fact_object[object_line_number])-1)),
 VALUES (fact_object[object_number])) 

我处于DirectQuery模式,因此计算列不存在很多函数,这就是我使用度量的原因。

完成后,我希望能够为每个绿色行获取前一个黄色行的date_modification

在这个例子中,结果将是 4/4 然后 1。这样我就可以计算当前绿色行的date_modification和前一个黄色行的date_modification之间的时间差。

所以我正在考虑添加一个名为date_received的新列,它是之前黄色行的 date_modification ; 在此处输入图像描述

从那里,我只需要保留绿色行并计算date_modificationdate_received之间的差异。

我最后的计算实际上是有这个:

结果=(date_modification 和 date_received 之间的日期差异 <= 15 分钟的绿色行数)/(DAY(date_modification)= DAY(date_received)的绿色行数)

但我不知道该怎么做。我曾尝试以与old_status措施相同的精神来做到这一点:

date_received = CALCULATE (
 MAX(fact_object[date_modification]),
 FILTER (
     ALL(fact_object), 
     (fact_object[object_line_number] =  MAX (fact_object[object_line_number])-1) &&  MY OTHER FILTERS
 ),
 VALUES (fact_object[object_number])

)

但没有成功。

在 SQL 中,等价物是这样的:

SELECT 
    SUM(CASE WHEN (DATEDIFF(MINUTE, T.date_received, T.date_planification) <= 15) THEN 1 ELSE 0 END)  /
    SUM(CASE WHEN (DAY(T.date_received) = DAY(T.date_planification)) THEN 1 ELSE 0 END) as result
FROM (
    SELECT *, T.status_id as current_status,
        LAG(T.date_modification) OVER(PARTITION BY T.object_number ORDER BY T.object_line_number) as date_received,
        T.date_modification as date_planification
    FROM 
    (
        select *,
            LAG (status_id) OVER(PARTITION BY object_number ORDER BY object_line_number) AS old_status
        from dbo.fact_object
    ) AS T
    WHERE ((T.status_id = 0 AND (T.old_status <> 0 OR T.object_line_number = 1) AND T.emergency_level = 1) OR (T.old_status = 0 AND T.status_id IN (2,3,4,5)))--974
) AS T
WHERE old_status = 0

(好吧,也许有一种更好的方法可以在我已经完成的 SQL 中做到这一点)。

我怎样才能做到这一点?

4

1 回答 1

0

在这种情况下,我将首先按对象对表格进行排序,然后按对象行号(或修改日期 - 但这些似乎不会因每一行而改变。)

复制表格

表 1 - 添加从 1 开始的索引 表 2 - 添加从 0 开始的索引

从 Table1 中,将其与 table2 合并,使用新的索引字段

展开 MergedStatus ID(重命名为 NextStatusID)和 Object(重命名为 NextObject)字段。

您现在可以创建一个新的条件列来比较两个状态字段。例如状态 2 = 如果 Object = NextObject 然后 [NextStatusID] else null

于 2017-01-17T07:20:11.370 回答