日期范围与一组其他日期范围之间的累积重叠天数

时间:2013-09-26 22:31:08

标签: google-sheets spreadsheet

我有一个Google电子表格,维护事件的历史记录及其出现日期(B列是开始日期,C列是结束日期):

Sheet A
| | A      | B         | C         |
|1| Event1 | 1/15/2013 | 2/20/2013 |
|2| Event2 | 3/1/2013  | 3/10/2013 |
|3| Event3 | 5/7/2013  | 5/9/2013  |

我想要做的是,在给定另一个日期范围的情况下,可以找出与这些事件中的任何重叠的总天数。例如,如果我的日期范围是2/1/2013至2013年3月15日,则计算应该能够确定与Event1重叠20天,与Event2重叠10天,以及0天与Event3重叠。把它们放在一起,我要显示的值是30。

这是一个示例第二张表,显示了我想要计算几个示例日期范围的列C的值:

Sheet B
| | A         | B         | C  |
|1| 2/1/2013  | 3/15/2013 | 30 |
|2| 3/20/2013 | 3/25/2013 | 0  |
|3| 5/1/2013  | 5/7/2013  | 1  |

我遇到的问题是,虽然我可以编写单元格表达式来表明SUM和FILTER几乎可以让我在那里,但我尝试的最后一步(我已经尝试了很多方法让它工作)似乎总是将我对所有事件的计算减少到单个标量,然后才能对每个事件求和。

例如,如果我为Sheet B的C1单元格写下面的内容,作为计算如何计算它的一步:

=SUM(MIN(B1,'Sheet A'!C:C) - MAX(A1,'Sheet A'!B:B))

然后,SUM显然包含负值,其中事件与所讨论的时间段不重叠。 (您可以调整公式并将其展开为工作表A的每一行以查看未编号的值。)

但是,如果我尝试使用下面的内容过滤掉那些不相交的行,我只得到一个'#N / A'结果。我猜这是因为FILTER函数不喜欢在求和的值和标准中使用相同的范围,但这只是猜测:

=SUM(FILTER( MIN(B1,'Sheet A'!C:C)-MAX(A1,'Sheet A'!B:B) ; MIN(B1,'Sheet A'!C:C)>MAX(A1,'Sheet A'!B:B) ))

如果我试图使用MAX()函数或IF()来清除由非交叉行产生的负值,则SUM返回0.我认为这是因为MAX和IF是减少数据范围我想在求和之前总结为单个标量变量。即SUM()在单个标量上运行。

=SUM( MAX(0, MIN(B1,'Sheet A'!C:C) - MAX(A1,'Sheet A'!B:B)) )

=SUM(IF( MIN(B1,'Sheet A'!C:C)>MAX(A1,'Sheet A'!B:B), MIN(B1,'Sheet A'!C:C) - MAX(A1,'Sheet A'!B:B), 0))

任何想法如何计算我想要的东西?我唯一的另一个想法就是将Sheet A爆炸出来,这样每行只能覆盖一天。然后找到相交天数的总和应该会更容易一些,但是向Sheet A添加新事件的工作量会大大增加。

2 个答案:

答案 0 :(得分:0)

尝试了许多不同方法让Google电子表格允许在整个柱状范围内每行评估IF,MAX,MIN,SUM,FILTER,SUMIF,ARRAYFORUMLA等(计算中涉及多个单列范围) ,但它们都是相同的大小,如果我可以让Google将每一行视为数据库条目类型的东西,一切都应该有效。)我放弃并重构了我的事件表,以便单个事件跨越多行和每行代表一个日历日。也就是说,上面的表A现在看起来像:

Sheet A
|  | A      | B         |
|1 | Event1 | 1/15/2013 |
...
|17|        | 1/31/2013 |
[18|        | 2/1/2013  |
...
|38|        | 2/20/2013 |
|39| Event2 | 3/1/2013  |
...
|49|        | 3/10/2013 |
|50| Event3 | 5/7/2013  |
|51|        | 5/8/2013  |
|52|        | 5/9/2013  |

这种方式没有复杂的范围与范围交叉计算,所以基于事件日是否在查询范围内的一个简单的FILTER()工作。

答案 1 :(得分:0)

要获取给定日期范围(SheetB!A2中的开始日期,SheetB!B2中的结束日期,结束日期为INCLUSIVE)与SheetA!B2:B中的开始日期和INCLUSIVE结束日期之间的重叠总和和SheetA!C2:C分别在C2中使用以下公式:

=SUM(ArrayFormula(IF((SheetA!$B$2:$B="")+(SheetA!$C$2:$C=""),"",IF((TRANSPOSE(INDEX(ArrayFormula(QUERY(TRANSPOSE({SheetA!$C$2:$C,$B2+0*SheetA!$C$2:$C}),"Select "&"MIN(Col"&JOIN(", MIN(Col",SEQUENCE(ROWS(SheetA!$C$2:$C))&")"),0)),2))-TRANSPOSE(INDEX(ArrayFormula(QUERY(TRANSPOSE({SheetA!$B$2:$B,$A2+0*SheetA!$B$2:$B}),"Select "&"MAX(Col"&JOIN(", MAX(Col",SEQUENCE(ROWS(SheetA!$B$2:$B))&")"),0)),2)))>=0,(TRANSPOSE(INDEX(ArrayFormula(QUERY(TRANSPOSE({SheetA!$C$2:$C,$B2+0*SheetA!$C$2:$C}),"Select "&"MIN(Col"&JOIN(", MIN(Col",SEQUENCE(ROWS(SheetA!$C$2:$C))&")"),0)),2))-TRANSPOSE(INDEX(ArrayFormula(QUERY(TRANSPOSE({SheetA!$B$2:$B,$A2+0*SheetA!$B$2:$B}),"Select "&"MAX(Col"&JOIN(", MAX(Col",SEQUENCE(ROWS(SheetA!$B$2:$B))&")"),0)),2)))+1,0))))

如果您的结束日期是专有的,请使用:

=SUM(ArrayFormula(IF((SheetA!$B$2:$B="")+(SheetA!$C$2:$C=""),"",IF((TRANSPOSE(INDEX(ArrayFormula(QUERY(TRANSPOSE({SheetA!$C$2:$C,$B2+0*SheetA!$C$2:$C}),"Select "&"MIN(Col"&JOIN(", MIN(Col",SEQUENCE(ROWS(SheetA!$C$2:$C))&")"),0)),2))-TRANSPOSE(INDEX(ArrayFormula(QUERY(TRANSPOSE({SheetA!$B$2:$B,$A2+0*SheetA!$B$2:$B}),"Select "&"MAX(Col"&JOIN(", MAX(Col",SEQUENCE(ROWS(SheetA!$B$2:$B))&")"),0)),2)))>0,(TRANSPOSE(INDEX(ArrayFormula(QUERY(TRANSPOSE({SheetA!$C$2:$C,$B2+0*SheetA!$C$2:$C}),"Select "&"MIN(Col"&JOIN(", MIN(Col",SEQUENCE(ROWS(SheetA!$C$2:$C))&")"),0)),2))-TRANSPOSE(INDEX(ArrayFormula(QUERY(TRANSPOSE({SheetA!$B$2:$B,$A2+0*SheetA!$B$2:$B}),"Select "&"MAX(Col"&JOIN(", MAX(Col",SEQUENCE(ROWS(SheetA!$B$2:$B))&")"),0)),2))),0))))

您可以将其向下拖动以获取SheetB中其他行的编号。

按行计算数组最大/最小值的问题已在此处解决:https://stackoverflow.com/a/64314420/3525368