提问人:M Nastri 提问时间:11/5/2023 最后编辑:M Nastri 更新时间:11/9/2023 访问量:89
检查系统事件中的开放式日期
Checking system events for open ended dates
问:
我正在构建多个系统的可靠性报告。我正在使用 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
答:
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"
评论
0赞
M Nastri
11/7/2023
谢谢。我测试了一下,它有效,但我的表有五十万行,需要很长时间才能更新。我使用了您展示的概念,但创建了列,而不是在“让我们...在块中达到相同的解决方案,它现在不到一分钟就会更新。当我稍后到达 PC 时,我会接受您的答案并发布我的更改。再次,非常感谢。
评论