Expand/explode 一个 Google 工作表 table 带有工单打开和关闭统计信息以显示每个月所有打开的工单

Expand/explode a Google Sheets table with ticket open and close stats to show all tickets open each month

我的工作example/sampleGoogleSheet:https://docs.google.com/spreadsheets/d/1AvAb_qnrrexYl5W5wAW6aA6P552T-prBxoONOis-XZM/edit?usp=sharing

我有一个来源 table,其中包含有关门票的信息。为了这个问题,只有三列很重要:

根据这些信息,我需要生成 metrics/reports 显示特定月份的内容:

  1. 当月开的工单
  2. 当月关闭的工单
  3. 打开的工单(之前打开但未关闭)

而且,我需要原始数据,而不仅仅是月度摘要。也就是说,我应该能够 select 一个月并显示符合上述三个条件的所有工单 ID。

使用此函数(我的示例 sheet 中的列 E-G)很容易获得前两个:

{
    QUERY(A2:C, "SELECT B, 'Opened', A WHERE A IS NOT NULL LABEL 'Opened' '' FORMAT B 'YYYY-MM'");
    QUERY(A2:C, "SELECT C, 'Closed', A WHERE C IS NOT NULL LABEL 'Closed' '' FORMAT C 'YYYY-MM'")
}

我卡在第三个了。我想弄清楚如何在每个月打开一张票。对于每个月开放的票证,应该有一行:

例如:

会变成:

| Month   | Status | Ticket ID |
|---------|--------|-----------|
| 2018-11 | Opened | ID0010    |
| 2018-12 | Open   | ID0010    |
| 2019-01 | Closed | ID0010    |
| 2018-08 | Opened | ID0019    |
| 2018-09 | Open   | ID0019    |
| 2018-10 | Open   | ID0019    |
| 2018-11 | Open   | ID0019    |
| 2018-12 | Open   | ID0019    |
| 2019-01 | Open   | ID0019    |
| 2019-02 | Open   | ID0019    |
| 2019-03 | Closed | ID0019    |

注意:打开和关闭工单的月份不会也显示工单的 "Open"。换句话说,一张票应该只有 "Open" 月份:

而且,如果工单尚未关闭,那么它将在今天之前每个月一行。

我想我可以使用 的公认解决方案中的概念,但由于数据量大,我遇到了错误。公式在我的样本 sheet.

的 I2 中

Text result of CONCATENATE is longer than the limit of 50000 characters.

所以我想知道是否有其他方法可以获得我需要的数据。我知道如何使用自定义函数执行此操作,但我希望尽可能避免使用自定义函数。

更新解决方案

我能够提取 player0 答案的关键部分并将其用于我的原始解决方案。简而言之,不是使用 CONCATENATE 来组合 columns/rows,而是使用 QUERY999^99 作为 header 计数(第三个参数),因为 QUERY 将合并所有行(使用 space 分隔符)。

最终公式为:

=ARRAYFORMULA(
    QUERY(
        SPLIT(
            TRANSPOSE(
                SPLIT(
                    QUERY(
                        TRANSPOSE(
                            TRIM(
                                QUERY(
                                    IF(
                                        A2:A <> "",
                                        A2:A & "," & EDATE(
                                            IFERROR(
                                                SPLIT(
                                                    REPT(
                                                        EOMONTH(B2:B, -1) + 1 & ",",
                                                        DATEDIF(
                                                            EOMONTH(B2:B, 0) + 1,
                                                            EOMONTH(
                                                                IF(
                                                                    C2:C <> "",
                                                                    C2:C,
                                                                    EDATE(TODAY(), 1)
                                                                ),
                                                                0
                                                            ),
                                                            "M"
                                                        )
                                                    ),
                                                    ","
                                                ),
                                                0
                                            ),
                                            TRANSPOSE(
                                                ROW(
                                                    INDIRECT(
                                                        "A1:A" & MAX(
                                                            IF(
                                                                B2:B <> "",
                                                                IFERROR(
                                                                    DATEDIF(
                                                                        EOMONTH(B2:B, 0) + 1,
                                                                        EOMONTH(
                                                                            IF(
                                                                                C2:C <> "",
                                                                                C2:C,
                                                                                EDATE(TODAY(), 1)
                                                                            ),
                                                                            0
                                                                        ),
                                                                        "M"
                                                                    ),
                                                                    0
                                                                ),
                                                            )
                                                        )
                                                    )
                                                )
                                            )
                                        ) & ";",
                                    ),
                                    ,
                                    999^99
                                )
                            )
                        ),
                        ,
                        999^99
                    ) & " ",
                    "; "
                )
            ),
            ","
        ),
        "SELECT Col2, 'Open', Col1 WHERE Col2 > 4000 LABEL 'Open' '' FORMAT Col2 'YYYY-MM'",
        0
    )
)

更新以使用 SEQUENCE

=ARRAYFORMULA(
    QUERY(
        SPLIT(
            TRANSPOSE(
                SPLIT(
                    QUERY(
                        TRANSPOSE(
                            TRIM(
                                QUERY(
                                    IF(
                                        A2:A <> "",
                                        A2:A & "," & EDATE(
                                            IFERROR(
                                                SPLIT(
                                                    REPT(
                                                        EOMONTH(B2:B, -1) + 1 & ",",
                                                        DATEDIF(
                                                            EOMONTH(B2:B, 0) + 1,
                                                            EOMONTH(
                                                                IF(
                                                                    C2:C <> "",
                                                                    C2:C,
                                                                    EDATE(TODAY(), 1)
                                                                ),
                                                                0
                                                            ),
                                                            "M"
                                                        )
                                                    ),
                                                    ","
                                                ),
                                                0
                                            ),
                                            SEQUENCE(
                                                1,
                                                MAX(
                                                    IF(
                                                        B2:B <> "",
                                                        IFERROR(
                                                            DATEDIF(
                                                                EOMONTH(B2:B, 0) + 1,
                                                                EOMONTH(
                                                                    IF(
                                                                        C2:C <> "",
                                                                        C2:C,
                                                                        EDATE(TODAY(), 1)
                                                                    ),
                                                                    0
                                                                ),
                                                                "M"
                                                            ),
                                                            0
                                                        ),
                                                    )
                                                )
                                            )
                                        ) & ";",
                                    ),
                                    ,
                                    999^99
                                )
                            )
                        ),
                        ,
                        999^99
                    ) & " ",
                    "; "
                )
            ),
            ","
        ),
        "SELECT Col2, 'Open', Col1 WHERE Col2 > 4000 LABEL 'Open' '' FORMAT Col2 'YYYY-MM'",
        0
    )
)

同样的逻辑:

=ARRAYFORMULA(UNIQUE(QUERY(SPLIT(TRANSPOSE(SPLIT(QUERY(TRANSPOSE(QUERY(TRANSPOSE(
 "♦"&FILTER(A2:A, B2:B<>"", C2:C<>"")&"♠"&SPLIT(REPT(FILTER(B2:B, B2:B<>"", C2:C<>"")+1&"♣",
 NETWORKDAYS(FILTER(B2:B, B2:B<>"", C2:C<>"")+1, FILTER(C2:C, B2:B<>"", C2:C<>""))), "♣")+
 TRANSPOSE(ROW(INDIRECT("A1:A"&MAX(
 NETWORKDAYS(FILTER(B2:B, B2:B<>"", C2:C<>"")+1, FILTER(C2:C, B2:B<>"", C2:C<>"")))))-1)&"♠")
 ,,999^99)),,999^99), "♦")), "♠"),
 "select Col2,'Open',Col1 where Col2>4000 label 'Open''' format Col2 'YYYY-MM'", 0)))


更新:

=ARRAYFORMULA(UNIQUE(QUERY(SPLIT(TRANSPOSE(SPLIT(QUERY(TRANSPOSE(QUERY(TRANSPOSE("♦"&
 FILTER(A2:A, B2:B<>"", C2:C<>"", MONTH(B2:B)<>MONTH(C2:C), YEAR(B2:B)<>YEAR(C2:C))&"♠"&EOMONTH(SPLIT(REPT(
 FILTER(B2:B, B2:B<>"", C2:C<>"", MONTH(B2:B)<>MONTH(C2:C), YEAR(B2:B)<>YEAR(C2:C))+1&"♣", DATEDIF(
 FILTER(B2:B, B2:B<>"", C2:C<>"", MONTH(B2:B)<>MONTH(C2:C), YEAR(B2:B)<>YEAR(C2:C))+1, 
 FILTER(C2:C, B2:B<>"", C2:C<>"", MONTH(B2:B)<>MONTH(C2:C), YEAR(B2:B)<>YEAR(C2:C)), "M")-1), "♣"),
 TRANSPOSE(ROW(INDIRECT("A1:A"&MAX(NETWORKDAYS(
 FILTER(B2:B, B2:B<>"", C2:C<>"", MONTH(B2:B)<>MONTH(C2:C), YEAR(B2:B)<>YEAR(C2:C))+1, 
 FILTER(C2:C, B2:B<>"", C2:C<>"", MONTH(B2:B)<>MONTH(C2:C), YEAR(B2:B)<>YEAR(C2:C))))))))&"♠")
 ,,999^99)),,999^99), "♦")), "♠"), 
 "select Col2,'Open',Col1 where Col2>4000 label 'Open''' format Col2 'YYYY-MM'", 0)))

更新:

我已经更新了我的解决方案,以使用一种我喜欢用来将 2D 数组转换为 2 列数据集的重新制表方法。下面这个公式在这个 sample sheet. 的 C1 中 您会在 F1 中看到一个类似的公式,它跳过爆炸,如果这是图表的目标,则只按月计算票数。 A1 中还有一个小公式,仅计算以月为单位的未结票证的最大长度。这在公式中多次使用,因此在视觉上为它提供一个辅助单元格很有帮助。如果您想避免使用任何辅助单元格,可以很容易地将其替换为大型公式来代替 A1 参考。

=ARRAYFORMULA(QUERY(VLOOKUP(SEQUENCE(COUNTA(Sheet1!A2:A)*A1,1,0)/A1+2,{ROW(Sheet1!A2:A),Sheet1!A2:A,IF(EDATE(EOMONTH(Sheet1!B2:B,-1)+1,SEQUENCE(1,A1,0))>EOMONTH(IFERROR(1/(1/Sheet1!C2:C),TODAY()),-1)+1,,EDATE(EOMONTH(Sheet1!B2:B,-1)+1,SEQUENCE(1,A1,0)))},MOD(SEQUENCE(COUNTA(Sheet1!A2:A)*A1,1,0),A1)*{0,1}+{2,3}),"where Col2 is not null label Col1'Ticket',Col2'Month'"))