检查系统事件中的开放式日期

Checking system events for open ended dates

提问人:M Nastri 提问时间:11/5/2023 最后编辑:M Nastri 更新时间:11/9/2023 访问量:89

问:

我正在构建多个系统的可靠性报告。我正在使用 Power Query 来准备数据。

源数据仅显示故障是否在任何给定日期开始或结束,而不显示系统是否在任何其他日期已经关闭(或启动),因此我必须生成该可用性数据。

我对齐了开始日期和结束日期,然后将每个间隔内的日期标记为不可用。对于所有其他日期,我将它们标记为可用。

在那之后,我发现一些系统在另一个故障开始之前就缺少一个故障结束。换句话说,他们开始出现故障,几天后又开始出现另一个故障(检查下面示例中的加热器)。这是不可能的,我需要从数据中删除第一个失败开始,但我很难找到解决方案。

未配对的故障开始/结束只允许在数据的结束/开始,不允许在中间。

输入示例:

名字 日期 失败
发电机 22/01/2020
发电机 23/01/2020 结束
发电机 24/01/2020
发电机 25/01/2020 开始
发电机 26/01/2020
发电机 27/01/2020 结束
发电机 28/01/2020
22/01/2020
23/01/2020 开始
24/01/2020
25/01/2020 结束
26/01/2020
27/01/2020 开始
28/01/2020
冷却器 22/01/2020
冷却器 23/01/2020 结束
冷却器 24/01/2020
冷却器 25/01/2020
冷却器 26/01/2020
冷却器 27/01/2020 开始
冷却器 28/01/2020
加热器 22/01/2020
加热器 23/01/2020 开始
加热器 24/01/2020 结束
加热器 25/01/2020 开始
加热器 26/01/2020
加热器 27/01/2020 开始
加热器 28/01/2020 结束

预期输出:

名字 日期 地位
发电机 22/01/2020
发电机 23/01/2020
发电机 24/01/2020 向上
发电机 25/01/2020
发电机 26/01/2020
发电机 27/01/2020
发电机 28/01/2020 向上
22/01/2020 向上
23/01/2020
24/01/2020
25/01/2020
26/01/2020 向上
27/01/2020
28/01/2020
冷却器 22/01/2020
冷却器 23/01/2020
冷却器 24/01/2020 向上
冷却器 25/01/2020 向上
冷却器 26/01/2020 向上
冷却器 27/01/2020
冷却器 28/01/2020
加热器 22/01/2020 向上
加热器 23/01/2020
加热器 24/01/2020
加热器 25/01/2020 向上
加热器 26/01/2020 向上
加热器 27/01/2020
加热器 28/01/2020

我尝试在网上寻找解决方案,但很难准确描述这个问题。

基于色谱柱的解决方案

改进 Sam Nseir 答案 我收到了以下查询。

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("hdIxC8MgEAXg/+IciDWxyV5KOxYyhgxC3dpYxP7/dpEXvBczyud59zjnWd386qNLIapGGdPqU2u00f+DWppCu41e16e80FfL7Uan5GKSV87VB4aj/mNZ/vi+PzRXho7OlFXkyWDJJNlEhgxDtZeY/RLCy/OtgNhKoGJ+kN0nEQDEI8BFiLt3aScEiC8B3pOQUP6t4CIOiMeBj2Xj5Qc=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Name = _t, Date = _t, Failure = _t]),
    SystemData = Table.TransformColumnTypes(Source,{{"Name", type text}, {"Date", type date}, {"Failure", type text}}),
    DatesColumnAdded = Table.Group(SystemData, {"Name"}, {{"Dates", each _, type nullable table[Name = nullable text, Date = nullable date, Failure = nullable text]}}),
    Merged = Table.NestedJoin(DatesColumnAdded, {"Name"}, SystemData, {"Name"}, "MergedData", JoinKind.Inner),
    Expanded = Table.ExpandTableColumn(Merged, "MergedData", {"Date", "Failure"}, {"Date", "Failure"}),
    PreviousFailureRow = Table.AddColumn(Expanded, "PreviousFailureRow", each Table.Max(Table.SelectRows([Dates], (inner)=>inner[Date]<[Date]), "Date")),
    NextFailureRow = Table.AddColumn(PreviousFailureRow, "NextFailureRow", each Table.Min(Table.SelectRows([Dates], (inner)=>inner[Date]>[Date]), "Date")),
    StatusAdded = Table.AddColumn(NextFailureRow, "Status", each
    if [Failure]=null and [PreviousFailureRow]<>null and [PreviousFailureRow][Failure]="End" then "Up" else
    if [Failure]=null and [NextFailureRow]<>null and [NextFailureRow][Failure]="Start" then "Up" else
    if [Failure]="Start" and [NextFailureRow]<>null and [NextFailureRow][Failure]="Start" then "Up" else
    if [Failure]="End" and [NextFailureRow]<>null and [NextFailureRow][Failure]="End" then "Down" else
    "Down", type text),
    OtherColumnsRemoved = Table.SelectColumns(StatusAdded, {"Name", "Date", "Failure", "Status"})
in
    OtherColumnsRemoved
PowerQuery M

评论

2赞 horseyride 11/5/2023
您需要提供示例输入数据(作为文本而不是图像)、所需的输出和明确的方向,如何从输入到输出
0赞 M Nastri 11/6/2023
更新了问题

答:

1赞 Sam Nseir 11/6/2023 #1

下面是 PowerQuery 中的解决方案。

let
    Source = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("hdIxC8MgEAXg/+IciDWxyV5KOxYyhgxC3dpYxP7/dpEXvBczyud59zjnWd386qNLIapGGdPqU2u00f+DWppCu41e16e80FfL7Uan5GKSV87VB4aj/mNZ/vi+PzRXho7OlFXkyWDJJNlEhgxDtZeY/RLCy/OtgNhKoGJ+kN0nEQDEI8BFiLt3aScEiC8B3pOQUP6t4CIOiMeBj2Xj5Qc=", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Name = _t, Date = _t, Failure = _t]),
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Name", type text}, {"Date", type date}, {"Failure", type text}}),
    #"Added Status" = Table.AddColumn(#"Changed Type", "Status", each
        let
          pName = [Name],
          pDate = [Date],
          pFailure = if [Failure] <> null and [Failure] <> "" then [Failure] else null,
          pSearch = Table.SelectRows(#"Changed Type", each [Name] = pName and [Failure] <> null and [Failure] <> ""),
          prevFailureRow = Table.Max(Table.SelectRows(pSearch, each [Date] < pDate), "Date"),
          prevFailure = if prevFailureRow = null then null else prevFailureRow[Failure],
          nextFailureRow = Table.Min(Table.SelectRows(pSearch, each [Date] > pDate), "Date"),
          nextFailure = if nextFailureRow = null then null else nextFailureRow[Failure],
          result = 
            if      pFailure = null and prevFailure = "End" then "Up"
            else if pFailure = null and nextFailure = "Start" then "Up"
            else if pFailure = "Start" and nextFailure = "Start" then "Up"
            else "Down"
        in
          result
    ,type text)
in
    #"Added Status"

enter image description here

评论

0赞 M Nastri 11/7/2023
谢谢。我测试了一下,它有效,但我的表有五十万行,需要很长时间才能更新。我使用了您展示的概念,但创建了列,而不是在“让我们...在块中达到相同的解决方案,它现在不到一分钟就会更新。当我稍后到达 PC 时,我会接受您的答案并发布我的更改。再次,非常感谢。