diff --git a/docs/asciidoc/modules/ROOT/pages/overview/apoc.agg/apoc.agg.multiStats.adoc b/docs/asciidoc/modules/ROOT/pages/overview/apoc.agg/apoc.agg.multiStats.adoc index 8d00f303bd..91e494ae00 100644 --- a/docs/asciidoc/modules/ROOT/pages/overview/apoc.agg/apoc.agg.multiStats.adoc +++ b/docs/asciidoc/modules/ROOT/pages/overview/apoc.agg/apoc.agg.multiStats.adoc @@ -22,7 +22,7 @@ apoc.agg.multiStats(value :: NODE | RELATIONSHIP, keys :: LIST OF STRING) :: (MA |=== -[[usage-apoc.data.email]] +[[usage-apoc.agg.multiStats]] == Usage Examples Given this dataset: diff --git a/docs/asciidoc/modules/ROOT/pages/overview/apoc.agg/apoc.agg.rollup.adoc b/docs/asciidoc/modules/ROOT/pages/overview/apoc.agg/apoc.agg.rollup.adoc new file mode 100644 index 0000000000..3d060fda96 --- /dev/null +++ b/docs/asciidoc/modules/ROOT/pages/overview/apoc.agg/apoc.agg.rollup.adoc @@ -0,0 +1,259 @@ + += apoc.agg.rollup +:description: This section contains reference documentation for the apoc.agg.rollup function. + +label:function[] label:apoc-extended[] + +[.emphasis] +apoc.agg.rollup(, [groupKeys], [aggKeys]) + +Emulate an Oracle/Mysql ROLLUP command: +`ROLLUP groupKeys, SUM(aggKey1), AVG(aggKey1), COUNT(aggKey1), SUM(aggKey2), AVG(aggKey2), ...`. + +Note that the `[NULL]` values (see the `Interpreting "[NULL]" Values in Results` section https://docs.oracle.com/cd/F49540_01/DOC/server.815/a68003/rollup_c.htm#32084[here]) +are returned by the procedure as `[NULL]`. + + + +== Signature + +[source] +---- +apoc.agg.rollup(value :: ANY | RELATIONSHIP, groupKeys :: LIST OF STRING, aggKeys :: LIST OF STRING) :: (MAP?) +---- + +== Config parameters +include::partial$usage/config/apoc.agg.rollup.adoc[] + +[[usage-apoc.agg.rollup]] +== Usage Examples + +Given this dataset: + +[source, cypher] +---- +CREATE (:Product {SupplierID: 1, CategoryID: 1, anotherID: 1, Price: 18, otherNum: 0.3}), + (:Product {SupplierID: 11, CategoryID: 3, anotherID: 1, Price: 14.0, otherNum: 0.1}), + (:Product {SupplierID: 11, CategoryID: 3, anotherID: 0, Price: 31.0, otherNum: 2}), + (:Product {SupplierID: 11, CategoryID: 4, anotherID: 0, Price: 44, otherNum: 0.7}), + (:Product {SupplierID: 1, CategoryID: null, anotherID: 1, Price: 18, otherNum: 0.7}), + (:Product {SupplierID: null, CategoryID: null, anotherID: 0, Price: 18, otherNum: 0.6}), + (:Product {SupplierID: null, CategoryID: 2, anotherID: 0, Price: 199, otherNum: 0.8}); +---- + +We can emulate a https://docs.oracle.com/cd/F49540_01/DOC/server.815/a68003/rollup_c.htm#32084[ROLLUP] clause +like this: +``` +SELECT SupplierID, CategoryID, anotherID, + SUM(Price), AVG(Price), COUNT(Price), SUM(otherNum), AVG(otherNum), COUNT(otherNum) + GROUP BY ROLLUP(SupplierID, CategoryID, anotherID) +``` + +by executing: + +[source, cypher] +---- +MATCH (p:Product) +RETURN apoc.agg.rollup(p, + ["SupplierID", "CategoryID", "anotherID"], + ["Price", "otherNum"] +) as data +---- + + +.Results +[opts="header"] +|=== +| data +a| +[source,json] +---- +[ + {"AVG(otherNum)":0.3,"CategoryID":1,"anotherID":1,"SUM(Price)":18,"COUNT(Price)":1,"AVG(Price)":18,"SUM(otherNum)":0.3,"SupplierID":1,"COUNT(otherNum)":1}, + {"AVG(otherNum)":0.3,"CategoryID":1,"anotherID":"[NULL]","SUM(Price)":18,"COUNT(Price)":1,"AVG(Price)":18,"SUM(otherNum)":0.3,"SupplierID":1,"COUNT(otherNum)":1}, + {"AVG(otherNum)":0.5,"CategoryID":"[NULL]","anotherID":"[NULL]","SUM(Price)":36,"COUNT(Price)":2,"AVG(Price)":18,"SUM(otherNum)":1,"SupplierID":1,"COUNT(otherNum)":2}, + {"AVG(otherNum)":0.7,"CategoryID":null,"anotherID":1,"SUM(Price)":18,"COUNT(Price)":1,"AVG(Price)":18,"SUM(otherNum)":0.7,"SupplierID":1,"COUNT(otherNum)":1}, + {"AVG(otherNum)":0.7,"CategoryID":null,"anotherID":"[NULL]","SUM(Price)":18,"COUNT(Price)":1,"AVG(Price)":18,"SUM(otherNum)":0.7,"SupplierID":1,"COUNT(otherNum)":1}, + {"AVG(otherNum)":2,"CategoryID":3,"anotherID":0,"SUM(Price)":31,"COUNT(Price)":1,"AVG(Price)":31,"SUM(otherNum)":2,"SupplierID":11,"COUNT(otherNum)":1}, + {"AVG(otherNum)":0.1,"CategoryID":3,"anotherID":1,"SUM(Price)":14,"COUNT(Price)":1,"AVG(Price)":14,"SUM(otherNum)":0.1,"SupplierID":11,"COUNT(otherNum)":1}, + {"AVG(otherNum)":1.05,"CategoryID":3,"anotherID":"[NULL]","SUM(Price)":45,"COUNT(Price)":2,"AVG(Price)":22.5,"SUM(otherNum)":2.1,"SupplierID":11,"COUNT(otherNum)":2}, + {"AVG(otherNum)":0.7,"CategoryID":4,"anotherID":0,"SUM(Price)":44,"COUNT(Price)":1,"AVG(Price)":44,"SUM(otherNum)":0.7,"SupplierID":11,"COUNT(otherNum)":1}, + {"AVG(otherNum)":0.7,"CategoryID":4,"anotherID":"[NULL]","SUM(Price)":44,"COUNT(Price)":1,"AVG(Price)":44,"SUM(otherNum)":0.7,"SupplierID":11,"COUNT(otherNum)":1}, + {"AVG(otherNum)":0.9333333333333332,"CategoryID":"[NULL]","anotherID":"[NULL]","SUM(Price)":89,"COUNT(Price)":3,"AVG(Price)":29.666666666666668,"SUM(otherNum)":2.8,"SupplierID":11,"COUNT(otherNum)":3}, + {"AVG(otherNum)":0.7428571428571428,"CategoryID":"[NULL]","anotherID":"[NULL]","SUM(Price)":342,"COUNT(Price)":7,"AVG(Price)":48.857142857142854,"SUM(otherNum)":5.199999999999999,"SupplierID":"[NULL]","COUNT(otherNum)":7}, + {"AVG(otherNum)":0.8,"CategoryID":2,"anotherID":0,"SUM(Price)":199,"COUNT(Price)":1,"AVG(Price)":199,"SUM(otherNum)":0.8,"SupplierID":null,"COUNT(otherNum)":1}, + {"AVG(otherNum)":0.8,"CategoryID":2,"anotherID":"[NULL]","SUM(Price)":199,"COUNT(Price)":1,"AVG(Price)":199,"SUM(otherNum)":0.8,"SupplierID":null,"COUNT(otherNum)":1}, + {"AVG(otherNum)":0.7,"CategoryID":"[NULL]","anotherID":"[NULL]","SUM(Price)":217,"COUNT(Price)":2,"AVG(Price)":108.5,"SUM(otherNum)":1.4,"SupplierID":null,"COUNT(otherNum)":2}, + {"AVG(otherNum)":0.6,"CategoryID":null,"anotherID":0,"SUM(Price)":18,"COUNT(Price)":1,"AVG(Price)":18,"SUM(otherNum)":0.6,"SupplierID":null,"COUNT(otherNum)":1}, + {"AVG(otherNum)":0.6,"CategoryID":null,"anotherID":"[NULL]","SUM(Price)":18,"COUNT(Price)":1,"AVG(Price)":18,"SUM(otherNum)":0.6,"SupplierID":null,"COUNT(otherNum)":1} +] +---- +|=== + +Note that the `[NULL]` values (see the `Interpreting "[NULL]" Values in Results` section https://docs.oracle.com/cd/F49540_01/DOC/server.815/a68003/rollup_c.htm#32084[here]) +are returned by the procedure as `[NULL]`. + + +or a ROLLUP clause like: +``` +SELECT CategoryID, SupplierID, anotherID, + SUM(Price), AVG(Price), COUNT(Price), SUM(otherNum), AVG(otherNum), COUNT(otherNum) + GROUP BY ROLLUP(CategoryID, SupplierID, anotherID) +``` + + +with this query: + +[source, cypher] +---- +MATCH (p:Product) +RETURN apoc.agg.rollup(p, + ["CategoryID", "SupplierID", "anotherID"], + ["Price", "otherNum"] +) as data +---- + + +.Results +[opts="header"] +|=== +| data +a| +[source,json] +---- +[ + { "AVG(otherNum)": 0.3, "CategoryID": 1, "anotherID": 1, "SUM(Price)": 18, "COUNT(Price)": 1, "AVG(Price)": 18.0, "SUM(otherNum)": 0.3, "SupplierID": 1, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.3, "CategoryID": 1, "anotherID": "[NULL]", "SUM(Price)": 18, "COUNT(Price)": 1, "AVG(Price)": 18.0, "SUM(otherNum)": 0.3, "SupplierID": 1, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.3, "CategoryID": 1, "anotherID": "[NULL]", "SUM(Price)": 18, "COUNT(Price)": 1, "AVG(Price)": 18.0, "SUM(otherNum)": 0.3, "SupplierID": "[NULL]", "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.8, "CategoryID": 2, "anotherID": "[NULL]", "SUM(Price)": 199, "COUNT(Price)": 1, "AVG(Price)": 199.0, "SUM(otherNum)": 0.8, "SupplierID": "[NULL]", "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.8, "CategoryID": 2, "anotherID": 0, "SUM(Price)": 199, "COUNT(Price)": 1, "AVG(Price)": 199.0, "SUM(otherNum)": 0.8, "SupplierID": null, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.8, "CategoryID": 2, "anotherID": "[NULL]", "SUM(Price)": 199, "COUNT(Price)": 1, "AVG(Price)": 199.0, "SUM(otherNum)": 0.8, "SupplierID": null, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 2.0, "CategoryID": 3, "anotherID": 0, "SUM(Price)": 31.0, "COUNT(Price)": 1, "AVG(Price)": 31.0, "SUM(otherNum)": 2, "SupplierID": 11, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.1, "CategoryID": 3, "anotherID": 1, "SUM(Price)": 14.0, "COUNT(Price)": 1, "AVG(Price)": 14.0, "SUM(otherNum)": 0.1, "SupplierID": 11, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 1.05, "CategoryID": 3, "anotherID": "[NULL]", "SUM(Price)": 45.0, "COUNT(Price)": 2, "AVG(Price)": 22.5, "SUM(otherNum)": 2.1, "SupplierID": 11, "COUNT(otherNum)": 2}, + { "AVG(otherNum)": 1.05, "CategoryID": 3, "anotherID": "[NULL]", "SUM(Price)": 45.0, "COUNT(Price)": 2, "AVG(Price)": 22.5, "SUM(otherNum)": 2.1, "SupplierID": "[NULL]", "COUNT(otherNum)": 2}, + { "AVG(otherNum)": 0.7, "CategoryID": 4, "anotherID": 0, "SUM(Price)": 44, "COUNT(Price)": 1, "AVG(Price)": 44.0, "SUM(otherNum)": 0.7, "SupplierID": 11, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.7, "CategoryID": 4, "anotherID": "[NULL]", "SUM(Price)": 44, "COUNT(Price)": 1, "AVG(Price)": 44.0, "SUM(otherNum)": 0.7, "SupplierID": 11, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.7, "CategoryID": 4, "anotherID": "[NULL]", "SUM(Price)": 44, "COUNT(Price)": 1, "AVG(Price)": 44.0, "SUM(otherNum)": 0.7, "SupplierID": "[NULL]", "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.7428571428571428, "CategoryID": "[NULL]", "anotherID": "[NULL]", "SUM(Price)": 342.0, "COUNT(Price)": 7, "AVG(Price)": 48.857142857142854, "SUM(otherNum)": 5.199999999999999, "SupplierID": "[NULL]", "COUNT(otherNum)": 7}, + { "AVG(otherNum)": 0.7, "CategoryID": null, "anotherID": 1, "SUM(Price)": 18, "COUNT(Price)": 1, "AVG(Price)": 18.0, "SUM(otherNum)": 0.7, "SupplierID": 1, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.7, "CategoryID": null, "anotherID": "[NULL]", "SUM(Price)": 18, "COUNT(Price)": 1, "AVG(Price)": 18.0, "SUM(otherNum)": 0.7, "SupplierID": 1, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.6499999999999999, "CategoryID": null, "anotherID": "[NULL]", "SUM(Price)": 36, "COUNT(Price)": 2, "AVG(Price)": 18.0, "SUM(otherNum)": 1.2999999999999998, "SupplierID": "[NULL]", "COUNT(otherNum)": 2}, + { "AVG(otherNum)": 0.6, "CategoryID": null, "anotherID": 0, "SUM(Price)": 18, "COUNT(Price)": 1, "AVG(Price)": 18.0, "SUM(otherNum)": 0.6, "SupplierID": null, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.6, "CategoryID": null, "anotherID": "[NULL]", "SUM(Price)": 18, "COUNT(Price)": 1, "AVG(Price)": 18.0, "SUM(otherNum)": 0.6, "SupplierID": null, "COUNT(otherNum)": 1} +] +---- +|=== + + +We can also emulate a https://docs.oracle.com/cd/F49540_01/DOC/server.815/a68003/rollup_c.htm#32311[CUBE] clause +like this: +``` +SELECT SupplierID, CategoryID, anotherID, + SUM(Price), AVG(Price), COUNT(Price), SUM(otherNum), AVG(otherNum), COUNT(otherNum) + GROUP BY CUBE(SupplierID, CategoryID, anotherID) +``` + + +executing: + +[source, cypher] +---- +MATCH (p:Product) +RETURN apoc.agg.rollup(p, + ["SupplierID", "CategoryID", "anotherID"], + ["Price", "otherNum"], + {cube: true} +) as data +---- + +.Results +[opts="header"] +|=== +| data +a| +[source,json] +---- +[ + { "AVG(otherNum)": 0.3, "CategoryID": 1, "anotherID": 1, "SUM(Price)": 18, "COUNT(Price)": 1, "AVG(Price)": 18.0, "SUM(otherNum)": 0.3, "SupplierID": 1, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.3, "CategoryID": 1, "anotherID": "[NULL]", "SUM(Price)": 18, "COUNT(Price)": 1, "AVG(Price)": 18.0, "SUM(otherNum)": 0.3, "SupplierID": 1, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.5666666666666667, "CategoryID": "[NULL]", "anotherID": 1, "SUM(Price)": 54, "COUNT(Price)": 3, "AVG(Price)": 18.0, "SUM(otherNum)": 1.7, "SupplierID": 1, "COUNT(otherNum)": 3}, + { "AVG(otherNum)": 0.5666666666666667, "CategoryID": "[NULL]", "anotherID": "[NULL]", "SUM(Price)": 54, "COUNT(Price)": 3, "AVG(Price)": 18.0, "SUM(otherNum)": 1.7, "SupplierID": 1, "COUNT(otherNum)": 3}, + { "AVG(otherNum)": 2.0, "CategoryID": 3, "anotherID": 0, "SUM(Price)": 31.0, "COUNT(Price)": 1, "AVG(Price)": 31.0, "SUM(otherNum)": 2, "SupplierID": 11, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.1, "CategoryID": 3, "anotherID": 1, "SUM(Price)": 14.0, "COUNT(Price)": 1, "AVG(Price)": 14.0, "SUM(otherNum)": 0.1, "SupplierID": 11, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 1.05, "CategoryID": 3, "anotherID": "[NULL]", "SUM(Price)": 45.0, "COUNT(Price)": 2, "AVG(Price)": 22.5, "SUM(otherNum)": 2.1, "SupplierID": 11, "COUNT(otherNum)": 2}, + { "AVG(otherNum)": 0.7, "CategoryID": 4, "anotherID": 0, "SUM(Price)": 44, "COUNT(Price)": 1, "AVG(Price)": 44.0, "SUM(otherNum)": 0.7, "SupplierID": 11, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.7, "CategoryID": 4, "anotherID": "[NULL]", "SUM(Price)": 44, "COUNT(Price)": 1, "AVG(Price)": 44.0, "SUM(otherNum)": 0.7, "SupplierID": 11, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 1.35, "CategoryID": "[NULL]", "anotherID": 0, "SUM(Price)": 75.0, "COUNT(Price)": 2, "AVG(Price)": 37.5, "SUM(otherNum)": 2.7, "SupplierID": 11, "COUNT(otherNum)": 2}, + { "AVG(otherNum)": 0.1, "CategoryID": "[NULL]", "anotherID": 1, "SUM(Price)": 14.0, "COUNT(Price)": 1, "AVG(Price)": 14.0, "SUM(otherNum)": 0.1, "SupplierID": 11, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.9333333333333332, "CategoryID": "[NULL]", "anotherID": "[NULL]", "SUM(Price)": 89.0, "COUNT(Price)": 3, "AVG(Price)": 29.666666666666668, "SUM(otherNum)": 2.8, "SupplierID": 11, "COUNT(otherNum)": 3}, + { "AVG(otherNum)": 0.3, "CategoryID": 1, "anotherID": 1, "SUM(Price)": 18, "COUNT(Price)": 1, "AVG(Price)": 18.0, "SUM(otherNum)": 0.3, "SupplierID": "[NULL]", "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.3, "CategoryID": 1, "anotherID": "[NULL]", "SUM(Price)": 18, "COUNT(Price)": 1, "AVG(Price)": 18.0, "SUM(otherNum)": 0.3, "SupplierID": "[NULL]", "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.8, "CategoryID": 2, "anotherID": 0, "SUM(Price)": 398, "COUNT(Price)": 2, "AVG(Price)": 199.0, "SUM(otherNum)": 1.6, "SupplierID": "[NULL]", "COUNT(otherNum)": 2}, + { "AVG(otherNum)": 0.8, "CategoryID": 2, "anotherID": "[NULL]", "SUM(Price)": 398, "COUNT(Price)": 2, "AVG(Price)": 199.0, "SUM(otherNum)": 1.6, "SupplierID": "[NULL]", "COUNT(otherNum)": 2}, + { "AVG(otherNum)": 2.0, "CategoryID": 3, "anotherID": 0, "SUM(Price)": 31.0, "COUNT(Price)": 1, "AVG(Price)": 31.0, "SUM(otherNum)": 2, "SupplierID": "[NULL]", "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.1, "CategoryID": 3, "anotherID": 1, "SUM(Price)": 14.0, "COUNT(Price)": 1, "AVG(Price)": 14.0, "SUM(otherNum)": 0.1, "SupplierID": "[NULL]", "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 1.05, "CategoryID": 3, "anotherID": "[NULL]", "SUM(Price)": 45.0, "COUNT(Price)": 2, "AVG(Price)": 22.5, "SUM(otherNum)": 2.1, "SupplierID": "[NULL]", "COUNT(otherNum)": 2}, + { "AVG(otherNum)": 0.7, "CategoryID": 4, "anotherID": 0, "SUM(Price)": 44, "COUNT(Price)": 1, "AVG(Price)": 44.0, "SUM(otherNum)": 0.7, "SupplierID": "[NULL]", "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.7, "CategoryID": 4, "anotherID": "[NULL]", "SUM(Price)": 44, "COUNT(Price)": 1, "AVG(Price)": 44.0, "SUM(otherNum)": 0.7, "SupplierID": "[NULL]", "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.8374999999999999, "CategoryID": "[NULL]", "anotherID": 0, "SUM(Price)": 545.0, "COUNT(Price)": 8, "AVG(Price)": 68.125, "SUM(otherNum)": 6.699999999999999, "SupplierID": "[NULL]", "COUNT(otherNum)": 8}, + { "AVG(otherNum)": 0.45, "CategoryID": "[NULL]", "anotherID": 1, "SUM(Price)": 68.0, "COUNT(Price)": 4, "AVG(Price)": 17.0, "SUM(otherNum)": 1.8, "SupplierID": "[NULL]", "COUNT(otherNum)": 4}, + { "AVG(otherNum)": 0.7083333333333331, "CategoryID": "[NULL]", "anotherID": "[NULL]", "SUM(Price)": 613.0, "COUNT(Price)": 12, "AVG(Price)": 51.083333333333336, "SUM(otherNum)": 8.499999999999998, "SupplierID": "[NULL]", "COUNT(otherNum)": 12} +] +---- +|=== + +or a CUBE clause like: +``` +SELECT CategoryID, SupplierID, anotherID, + SUM(Price), AVG(Price), COUNT(Price), SUM(otherNum), AVG(otherNum), COUNT(otherNum) + GROUP BY CUBE(CategoryID, SupplierID, anotherID) +``` + + +with this query: +[source, cypher] +---- +MATCH (p:Product) +RETURN apoc.agg.rollup(p, + ["CategoryID", "SupplierID", "anotherID"], + ["Price", "otherNum"], + {cube: true} +) as data +---- + +.Results +[opts="header"] +|=== +| data +a| +[source,json] +---- +[ + { "AVG(otherNum)": 0.3, "CategoryID": 1, "anotherID": 1, "SUM(Price)": 18, "COUNT(Price)": 1, "AVG(Price)": 18.0, "SUM(otherNum)": 0.3, "SupplierID": 1, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.3, "CategoryID": 1, "anotherID": "[NULL]", "SUM(Price)": 18, "COUNT(Price)": 1, "AVG(Price)": 18.0, "SUM(otherNum)": 0.3, "SupplierID": 1, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.3, "CategoryID": 1, "anotherID": 1, "SUM(Price)": 18, "COUNT(Price)": 1, "AVG(Price)": 18.0, "SUM(otherNum)": 0.3, "SupplierID": "[NULL]", "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.3, "CategoryID": 1, "anotherID": "[NULL]", "SUM(Price)": 18, "COUNT(Price)": 1, "AVG(Price)": 18.0, "SUM(otherNum)": 0.3, "SupplierID": "[NULL]", "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.8, "CategoryID": 2, "anotherID": 0, "SUM(Price)": 398, "COUNT(Price)": 2, "AVG(Price)": 199.0, "SUM(otherNum)": 1.6, "SupplierID": "[NULL]", "COUNT(otherNum)": 2}, + { "AVG(otherNum)": 0.8, "CategoryID": 2, "anotherID": "[NULL]", "SUM(Price)": 398, "COUNT(Price)": 2, "AVG(Price)": 199.0, "SUM(otherNum)": 1.6, "SupplierID": "[NULL]", "COUNT(otherNum)": 2}, + { "AVG(otherNum)": 2.0, "CategoryID": 3, "anotherID": 0, "SUM(Price)": 31.0, "COUNT(Price)": 1, "AVG(Price)": 31.0, "SUM(otherNum)": 2, "SupplierID": 11, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.1, "CategoryID": 3, "anotherID": 1, "SUM(Price)": 14.0, "COUNT(Price)": 1, "AVG(Price)": 14.0, "SUM(otherNum)": 0.1, "SupplierID": 11, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 1.05, "CategoryID": 3, "anotherID": "[NULL]", "SUM(Price)": 45.0, "COUNT(Price)": 2, "AVG(Price)": 22.5, "SUM(otherNum)": 2.1, "SupplierID": 11, "COUNT(otherNum)": 2}, + { "AVG(otherNum)": 2.0, "CategoryID": 3, "anotherID": 0, "SUM(Price)": 31.0, "COUNT(Price)": 1, "AVG(Price)": 31.0, "SUM(otherNum)": 2, "SupplierID": "[NULL]", "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.1, "CategoryID": 3, "anotherID": 1, "SUM(Price)": 14.0, "COUNT(Price)": 1, "AVG(Price)": 14.0, "SUM(otherNum)": 0.1, "SupplierID": "[NULL]", "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 1.05, "CategoryID": 3, "anotherID": "[NULL]", "SUM(Price)": 45.0, "COUNT(Price)": 2, "AVG(Price)": 22.5, "SUM(otherNum)": 2.1, "SupplierID": "[NULL]", "COUNT(otherNum)": 2}, + { "AVG(otherNum)": 0.7, "CategoryID": 4, "anotherID": 0, "SUM(Price)": 44, "COUNT(Price)": 1, "AVG(Price)": 44.0, "SUM(otherNum)": 0.7, "SupplierID": 11, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.7, "CategoryID": 4, "anotherID": "[NULL]", "SUM(Price)": 44, "COUNT(Price)": 1, "AVG(Price)": 44.0, "SUM(otherNum)": 0.7, "SupplierID": 11, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.7, "CategoryID": 4, "anotherID": 0, "SUM(Price)": 44, "COUNT(Price)": 1, "AVG(Price)": 44.0, "SUM(otherNum)": 0.7, "SupplierID": "[NULL]", "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.7, "CategoryID": 4, "anotherID": "[NULL]", "SUM(Price)": 44, "COUNT(Price)": 1, "AVG(Price)": 44.0, "SUM(otherNum)": 0.7, "SupplierID": "[NULL]", "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.5666666666666667, "CategoryID": "[NULL]", "anotherID": 1, "SUM(Price)": 54, "COUNT(Price)": 3, "AVG(Price)": 18.0, "SUM(otherNum)": 1.7, "SupplierID": 1, "COUNT(otherNum)": 3}, + { "AVG(otherNum)": 0.5666666666666667, "CategoryID": "[NULL]", "anotherID": "[NULL]", "SUM(Price)": 54, "COUNT(Price)": 3, "AVG(Price)": 18.0, "SUM(otherNum)": 1.7, "SupplierID": 1, "COUNT(otherNum)": 3}, + { "AVG(otherNum)": 1.35, "CategoryID": "[NULL]", "anotherID": 0, "SUM(Price)": 75.0, "COUNT(Price)": 2, "AVG(Price)": 37.5, "SUM(otherNum)": 2.7, "SupplierID": 11, "COUNT(otherNum)": 2}, + { "AVG(otherNum)": 0.1, "CategoryID": "[NULL]", "anotherID": 1, "SUM(Price)": 14.0, "COUNT(Price)": 1, "AVG(Price)": 14.0, "SUM(otherNum)": 0.1, "SupplierID": 11, "COUNT(otherNum)": 1}, + { "AVG(otherNum)": 0.9333333333333332, "CategoryID": "[NULL]", "anotherID": "[NULL]", "SUM(Price)": 89.0, "COUNT(Price)": 3, "AVG(Price)": 29.666666666666668, "SUM(otherNum)": 2.8, "SupplierID": 11, "COUNT(otherNum)": 3}, + { "AVG(otherNum)": 0.8374999999999999, "CategoryID": "[NULL]", "anotherID": 0, "SUM(Price)": 545.0, "COUNT(Price)": 8, "AVG(Price)": 68.125, "SUM(otherNum)": 6.699999999999999, "SupplierID": "[NULL]", "COUNT(otherNum)": 8}, + { "AVG(otherNum)": 0.45, "CategoryID": "[NULL]", "anotherID": 1, "SUM(Price)": 68.0, "COUNT(Price)": 4, "AVG(Price)": 17.0, "SUM(otherNum)": 1.8, "SupplierID": "[NULL]", "COUNT(otherNum)": 4}, + { "AVG(otherNum)": 0.7083333333333331, "CategoryID": "[NULL]", "anotherID": "[NULL]", "SUM(Price)": 613.0, "COUNT(Price)": 12, "AVG(Price)": 51.083333333333336, "SUM(otherNum)": 8.499999999999998, "SupplierID": "[NULL]", "COUNT(otherNum)": 12} +] +---- +|=== \ No newline at end of file diff --git a/docs/asciidoc/modules/ROOT/pages/overview/apoc.agg/index.adoc b/docs/asciidoc/modules/ROOT/pages/overview/apoc.agg/index.adoc index 3a17e857f1..3a69a7b0ce 100644 --- a/docs/asciidoc/modules/ROOT/pages/overview/apoc.agg/index.adoc +++ b/docs/asciidoc/modules/ROOT/pages/overview/apoc.agg/index.adoc @@ -81,5 +81,13 @@ Returns index of the `element` that match the given `predicate` apoc.agg.multiStats(nodeOrRel, keys) - Return a multi-dimensional aggregation |label:function[] |label:apoc-full[] + +|xref::overview/apoc.agg/apoc.agg.rollup.adoc[apoc.agg.rollup icon:book[]] + +apoc.agg.rollup(, [groupKeys], [aggKeys]) + +Emulate an Oracle/Mysql rollup command: `ROLLUP groupKeys, SUM(aggKey1), AVG(aggKey1), COUNT(aggKey1), SUM(aggKey2), AVG(aggKey2), ... ` +|label:function[] +|label:apoc-full[] |=== diff --git a/docs/asciidoc/modules/ROOT/partials/generated-documentation/documentation.adoc b/docs/asciidoc/modules/ROOT/partials/generated-documentation/documentation.adoc index d3d94cbd08..d155debf20 100644 --- a/docs/asciidoc/modules/ROOT/partials/generated-documentation/documentation.adoc +++ b/docs/asciidoc/modules/ROOT/partials/generated-documentation/documentation.adoc @@ -218,6 +218,13 @@ apoc.bitwise.op(60,'\|',13) bitwise operations a & b, a \| b, a ^ b, ~a, a >> b, apoc.agg.multiStats(nodeOrRel, keys) - Return a multi-dimensional aggregation |label:procedure[] + +|xref::overview/apoc.agg/apoc.agg.rollup.adoc[apoc.agg.rollup icon:book[]] + +apoc.agg.rollup(, [groupKeys], [aggKeys]) + +Emulate an Oracle/Mysql rollup command: `ROLLUP groupKeys, SUM(aggKey1), AVG(aggKey1), COUNT(aggKey1), SUM(aggKey2), AVG(aggKey2), ... ` +|label:procedure[] |=== diff --git a/docs/asciidoc/modules/ROOT/partials/generated-documentation/nav.adoc b/docs/asciidoc/modules/ROOT/partials/generated-documentation/nav.adoc index 6bdb5bbfd5..5b34f96cb1 100644 --- a/docs/asciidoc/modules/ROOT/partials/generated-documentation/nav.adoc +++ b/docs/asciidoc/modules/ROOT/partials/generated-documentation/nav.adoc @@ -41,6 +41,7 @@ This file is generated by DocsTest, so don't change it! *** xref::overview/apoc.atomic/apoc.atomic.update.adoc[] ** xref::overview/apoc.bitwise/index.adoc[] *** xref::overview/apoc.bitwise/apoc.bitwise.op.adoc[] +*** xref::overview/apoc.agg/apoc.agg.rollup.adoc[] ** xref::overview/apoc.bolt/index.adoc[] *** xref::overview/apoc.bolt/apoc.bolt.execute.adoc[] *** xref::overview/apoc.bolt/apoc.bolt.load.adoc[] diff --git a/docs/asciidoc/modules/ROOT/partials/usage/config/apoc.agg.rollup.adoc b/docs/asciidoc/modules/ROOT/partials/usage/config/apoc.agg.rollup.adoc new file mode 100644 index 0000000000..8a254f6300 --- /dev/null +++ b/docs/asciidoc/modules/ROOT/partials/usage/config/apoc.agg.rollup.adoc @@ -0,0 +1,9 @@ +The procedure support the following properties in the APOC configuration file (`apoc.conf`): + +.Config parameters +[opts=header, cols="1,1,1,3"] +|=== +| name | type | default | description +| cube | boolean | false| to emulate the https://docs.oracle.com/cd/F49540_01/DOC/server.815/a68003/rollup_c.htm#32311[CUBE] clause, + instead of the https://docs.oracle.com/cd/F49540_01/DOC/server.815/a68003/rollup_c.htm#32084[ROLLUP] one. +|=== \ No newline at end of file diff --git a/full/src/main/java/apoc/agg/AggregationUtil.java b/full/src/main/java/apoc/agg/AggregationUtil.java new file mode 100644 index 0000000000..9280d3fe63 --- /dev/null +++ b/full/src/main/java/apoc/agg/AggregationUtil.java @@ -0,0 +1,51 @@ +package apoc.agg; + +import java.util.Map; + +public class AggregationUtil { + + public static void updateAggregationValues( + Map partialResult, Object property, String countKey, String sumKey, String avgKey) { + Number count = updateCountValue(partialResult, countKey); + + updateSumAndAvgValues(partialResult, property, count.doubleValue(), sumKey, avgKey); + } + + private static Number updateCountValue(Map partialResult, String countKey) { + Number count = partialResult.compute(countKey, ((subKey, subVal) -> { + return subVal == null ? 1 : subVal.longValue() + 1; + })); + return count; + } + + private static void updateSumAndAvgValues( + Map partialResult, Object property, double count, String sumKey, String avgKey) { + if (!(property instanceof Number)) { + return; + } + + Number numberProp = (Number) property; + + Number sum = partialResult.compute(sumKey, ((subKey, subVal) -> { + if (subVal == null) { + if (numberProp instanceof Long) { + return numberProp; + } + return numberProp.doubleValue(); + } + if (subVal instanceof Long && numberProp instanceof Long) { + Long long2 = (Long) numberProp; + Long long1 = (Long) subVal; + return long1 + long2; + } + return subVal.doubleValue() + numberProp.doubleValue(); + })); + + partialResult.compute(avgKey, ((subKey, subVal) -> { + if (subVal == null) { + return numberProp.doubleValue(); + } + return sum.doubleValue() / count; + })); + } +} diff --git a/full/src/main/java/apoc/agg/MultiStats.java b/full/src/main/java/apoc/agg/MultiStats.java index 49a28700fd..8df54507c8 100644 --- a/full/src/main/java/apoc/agg/MultiStats.java +++ b/full/src/main/java/apoc/agg/MultiStats.java @@ -1,5 +1,7 @@ package apoc.agg; +import static apoc.agg.AggregationUtil.updateAggregationValues; + import apoc.Extended; import java.util.HashMap; import java.util.List; @@ -38,26 +40,13 @@ public void aggregate(@Name("value") Object value, @Name(value = "keys") List { Map propMap = Objects.requireNonNullElseGet(propVal, HashMap::new); - Number count = propMap.compute( - "count", ((subKey, subVal) -> subVal == null ? 1 : subVal.longValue() + 1)); - if (property instanceof Number) { - Number numberProp = (Number) property; - Number sum = propMap.compute("sum", ((subKey, subVal) -> { - if (subVal == null) return numberProp; - if (subVal instanceof Long && numberProp instanceof Long) { - Long long2 = (Long) numberProp; - Long long1 = (Long) subVal; - return long1 + long2; - } - return subVal.doubleValue() + numberProp.doubleValue(); - })); - propMap.compute( - "avg", - ((subKey, subVal) -> subVal == null - ? numberProp.doubleValue() - : sum.doubleValue() / count.doubleValue())); - } + String countKey = "count"; + String sumKey = "sum"; + String avgKey = "avg"; + + updateAggregationValues(propMap, property, countKey, sumKey, avgKey); + return propMap; }); return map; diff --git a/full/src/main/java/apoc/agg/Rollup.java b/full/src/main/java/apoc/agg/Rollup.java new file mode 100644 index 0000000000..52d0ad1d5c --- /dev/null +++ b/full/src/main/java/apoc/agg/Rollup.java @@ -0,0 +1,195 @@ +package apoc.agg; + +import static apoc.agg.AggregationUtil.updateAggregationValues; + +import apoc.Extended; +import apoc.util.Util; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.apache.commons.collections4.ListUtils; +import org.neo4j.graphdb.Entity; +import org.neo4j.procedure.Description; +import org.neo4j.procedure.Name; +import org.neo4j.procedure.UserAggregationFunction; +import org.neo4j.procedure.UserAggregationResult; +import org.neo4j.procedure.UserAggregationUpdate; + +@Extended +public class Rollup { + public static final String NULL_ROLLUP = "[NULL]"; + + @UserAggregationFunction("apoc.agg.rollup") + @Description( + "apoc.agg.rollup(, [groupKeys], [aggKeys])" + + "\n Emulate an Oracle/Mysql rollup command: `ROLLUP groupKeys, SUM(aggKey1), AVG(aggKey1), COUNT(aggKey1), SUM(aggKey2), AVG(aggKey2), ... `") + public RollupFunction rollup() { + return new RollupFunction(); + } + + public static class RollupFunction { + // Function to generate all combinations of a list with "TEST" as a placeholder + public static List> generateCombinationsWithPlaceholder(List elements) { + List> result = new ArrayList<>(); + generateCombinationsWithPlaceholder(elements, 0, new ArrayList<>(), result); + return result; + } + + // Helper function for generating combinations recursively + private static void generateCombinationsWithPlaceholder( + List elements, int index, List current, List> result) { + if (index == elements.size()) { + result.add(new ArrayList<>(current)); + return; + } + + current.add(elements.get(index)); + generateCombinationsWithPlaceholder(elements, index + 1, current, result); + current.remove(current.size() - 1); + + // Add "NULL" as a combination placeholder + current.add((T) NULL_ROLLUP); + generateCombinationsWithPlaceholder(elements, index + 1, current, result); + current.remove(current.size() - 1); + } + + private final Map result = new HashMap<>(); + + private final Map, Map> rolledUpData = new HashMap<>(); + private List groupKeysRes = null; + + @UserAggregationUpdate + public void aggregate( + @Name("value") Object value, + @Name(value = "groupKeys") List groupKeys, + @Name(value = "aggKeys") List aggKeys, + @Name(value = "config", defaultValue = "{}") Map config) { + + boolean cube = Util.toBoolean(config.get("cube")); + + Entity entity = (Entity) value; + + if (groupKeys.isEmpty()) { + return; + } + groupKeysRes = groupKeys; + + /* + if true: + emulate the CUBE command: https://docs.oracle.com/cd/F49540_01/DOC/server.815/a68003/rollup_c.htm#32311 + else: + emulate the ROLLUP command: https://docs.oracle.com/cd/F49540_01/DOC/server.815/a68003/rollup_c.htm#32084 + */ + if (cube) { + List> groupingSets = generateCombinationsWithPlaceholder(groupKeys); + + for (List groupKey : groupingSets) { + List partialKey = new ArrayList<>(); + for (String column : groupKey) { + partialKey.add(((Entity) value).getProperty(column, NULL_ROLLUP)); + } + if (!rolledUpData.containsKey(partialKey)) { + rolledUpData.put(partialKey, new HashMap<>()); + } + rollupAggregationProperties(aggKeys, entity, partialKey); + } + + return; + } + + List groupKey = + groupKeys.stream().map(i -> entity.getProperty(i, null)).collect(Collectors.toList()); + + for (int i = 0; i <= groupKey.size(); i++) { + // add NULL_ROLLUP to remaining elements, + // e.g. `[, `NULL_ROLLUP`, `NULL_ROLLUP`]` + List partialKey = + ListUtils.union(groupKey.subList(0, i), Collections.nCopies(groupKey.size() - i, NULL_ROLLUP)); + if (!rolledUpData.containsKey(partialKey)) { + rolledUpData.put(partialKey, new HashMap<>()); + } + rollupAggregationProperties(aggKeys, entity, partialKey); + } + } + + private void rollupAggregationProperties(List aggKeys, Entity entity, List partialKey) { + Map partialResult = rolledUpData.get(partialKey); + for (var aggKey : aggKeys) { + if (!entity.hasProperty(aggKey)) { + continue; + } + + Object property = entity.getProperty(aggKey); + + String countKey = String.format("COUNT(%s)", aggKey); + String sumKey = String.format("SUM(%s)", aggKey); + String avgKey = String.format("AVG(%s)", aggKey); + + updateAggregationValues(partialResult, property, countKey, sumKey, avgKey); + } + } + + /** + * Transform a Map.of(ListGroupKeys, MapOfAggResults) in a List of Map.of(AggResult + ListGroupKeyToMap) + */ + @UserAggregationResult + public Object result() { + List> list = rolledUpData.entrySet().stream() + .map(e -> { + HashMap map = new HashMap<>(); + for (int i = 0; i < groupKeysRes.size(); i++) { + map.put(groupKeysRes.get(i), e.getKey().get(i)); + } + map.putAll(e.getValue()); + return map; + }) + .sorted((m1, m2) -> { + for (String key : groupKeysRes) { + Object value1 = m1.get(key); + Object value2 = m2.get(key); + int cmp = compareValues(value1, value2); + if (cmp != 0) { + return cmp; + } + } + return 0; + }) + .collect(Collectors.toList()); + + return list; + } + + /** + * We use this instead of e.g. apoc.coll.sortMulti + * since we have to handle the NULL_ROLLUP values as well + */ + private static int compareValues(Object value1, Object value2) { + if (value1 == null && value2 == null) { + return 0; + } else if (value1 == null) { + return 1; + } else if (value2 == null) { + return -1; + } else if (NULL_ROLLUP.equals(value1) && NULL_ROLLUP.equals(value2)) { + return 0; + } else if (NULL_ROLLUP.equals(value1)) { + return 1; + } else if (NULL_ROLLUP.equals(value2)) { + return -1; + } else if (value1 instanceof Comparable && value2 instanceof Comparable) { + try { + return ((Comparable) value1).compareTo(value2); + } catch (Exception e) { + // e.g. different data types, like int and strings + return 0; + } + + } else { + return 0; + } + } + } +} diff --git a/full/src/main/resources/extended.txt b/full/src/main/resources/extended.txt index 4bade733ed..b9791b648e 100644 --- a/full/src/main/resources/extended.txt +++ b/full/src/main/resources/extended.txt @@ -1,6 +1,7 @@ apoc.agg.position apoc.agg.row apoc.agg.multiStats +apoc.agg.rollup apoc.algo.aStarWithPoint apoc.algo.travellingSalesman apoc.bolt.execute diff --git a/full/src/test/java/apoc/agg/RollupTest.java b/full/src/test/java/apoc/agg/RollupTest.java new file mode 100644 index 0000000000..d60b5b3a64 --- /dev/null +++ b/full/src/test/java/apoc/agg/RollupTest.java @@ -0,0 +1,140 @@ +package apoc.agg; + +import static apoc.agg.RollupTestUtil.*; +import static apoc.util.ExtendedTestUtil.assertMapEquals; +import static apoc.util.TestUtil.testCall; +import static apoc.util.Util.map; + +import apoc.map.Maps; +import apoc.util.TestUtil; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; +import org.neo4j.test.rule.DbmsRule; +import org.neo4j.test.rule.ImpermanentDbmsRule; + +public class RollupTest { + @ClassRule + public static DbmsRule db = new ImpermanentDbmsRule(); + + @BeforeClass + public static void setUp() { + TestUtil.registerProcedure(db, Maps.class, Rollup.class); + + /* + + Similar to CREATE TABLE Products(SupplierID NUMBER(5,2), CategoryID NUMBER(5,2), Price NUMBER(5,2), otherNum FLOAT(5), anotherID NUMBER(5,2)); + + INSERT INTO Products VALUES(1, 1, 1, 18, 0.3); + INSERT INTO Products VALUES(1, 1, 0, 19, 0.5); + ... + */ + String query = "CREATE (:Product {SupplierID: 1, CategoryID: 1, anotherID: 1, Price: 18, otherNum: 0.3}),\n" + + " (:Product {SupplierID: 1, CategoryID: 1, anotherID: 0, Price: 19, otherNum: 0.5}),\n" + + " (:Product {SupplierID: 1, CategoryID: 2, anotherID: 1, Price: 10, otherNum: 0.6}),\n" + + " (:Product {SupplierID: 4, CategoryID: 8, anotherID: 0, Price: 31, otherNum: 0.6}),\n" + + " (:Product {SupplierID: 5, CategoryID: 4, anotherID: 1, Price: 21, otherNum: 0.2}),\n" + + " (:Product {SupplierID: 6, CategoryID: 8, anotherID: 1, Price: 6, otherNum: 0.5}),\n" + + " (:Product {SupplierID: 6, CategoryID: 7, anotherID: 1, Price: 23, otherNum: 0.6}),\n" + + " (:Product {SupplierID: 7, CategoryID: 3, anotherID: 1, Price: 17, otherNum: 0.7}),\n" + + " (:Product {SupplierID: 7, CategoryID: 6, anotherID: 1, Price: 39, otherNum: 0.8}),\n" + + " (:Product {SupplierID: 7, CategoryID: 8, anotherID: 1, Price: 63, otherNum: 0.9}),\n" + + " (:Product {SupplierID: 8, CategoryID: 3, anotherID: 0, Price: 9, otherNum: 0.2}),\n" + + " (:Product {SupplierID: 8, CategoryID: 3, anotherID: 1, Price: 81, otherNum: 0.5}),\n" + + " (:Product {SupplierID: 9, CategoryID: 5, anotherID: 0, Price: 9, otherNum: 0.9}),\n" + + " (:Product {SupplierID: 10, CategoryID: 1, anotherID: 1, Price: 5, otherNum: 0.2}),\n" + + " (:Product {SupplierID: 11, CategoryID: 3, anotherID: 1, Price: 14.0, otherNum: 0.1}),\n" + + " (:Product {SupplierID: 11, CategoryID: 3, anotherID: 0, Price: 31.0, otherNum: 2}),\n" + + " (:Product {SupplierID: 11, CategoryID: 4, anotherID: 0, Price: 44, otherNum: 0.7}),\n" + + " (:Product {SupplierID: 1, CategoryID: NULL, anotherID: 1, Price: 18, otherNum: 0.7}),\n" + + " (:Product {SupplierID: NULL, CategoryID: NULL, anotherID: 0, Price: 18, otherNum: 0.6}),\n" + + " (:Product {SupplierID: NULL, CategoryID: 2, anotherID: 0, Price: 199, otherNum: 0.8})"; + db.executeTransactionally(query); + } + + @AfterClass + public static void tearDown() { + db.shutdown(); + } + + // similar to https://docs.oracle.com/cd/F49540_01/DOC/server.815/a68003/rollup_c.htm#32084 + // and MySql `WITH ROLLUP` command + @Test + public void testRollupRespectivelySupplierIDCategoryIDAndAnotherID() { + + List expected = getRollupTripleGroup(); + String call = "MATCH (p:Product) RETURN apoc.agg.rollup(p, $groupKeys, [\"Price\", \"otherNum\"]) as data"; + testCall(db, call, map("groupKeys", List.of(SUPPLIER_ID, CATEGORY_ID, ANOTHER_ID)), r -> { + assertRollupCommon(expected, r); + }); + } + + @Test + public void testRollupRespectivelyCategoryIDSupplierIDAndAnotherID() { + + List expected = getRollupTripleGroupTwo(); + String call = "MATCH (p:Product) RETURN apoc.agg.rollup(p, $groupKeys, [\"Price\", \"otherNum\"]) as data"; + testCall(db, call, map("groupKeys", List.of(CATEGORY_ID, SUPPLIER_ID, ANOTHER_ID)), r -> { + assertRollupCommon(expected, r); + }); + } + + @Test + public void testRollupWithSingleAggregationKey() { + + List expected = getRollupTripleGroupTwo().stream() + .peek(i -> { + i.remove(sumOtherNum); + i.remove(countOtherNum); + i.remove(avgOtherNum); + }) + .collect(Collectors.toList()); + String call = "MATCH (p:Product) RETURN apoc.agg.rollup(p, $groupKeys, [\"Price\"]) as data"; + testCall(db, call, map("groupKeys", List.of(CATEGORY_ID, SUPPLIER_ID, ANOTHER_ID)), r -> { + assertRollupCommon(expected, r); + }); + } + + // similar to https://docs.oracle.com/cd/F49540_01/DOC/server.815/a68003/rollup_c.htm#32311 + @Test + public void testCubeRespectivelySupplierIDCategoryIDAndAnotherID() { + + List expected = getCubeTripleGroupTwo(); + String call = + "MATCH (p:Product) RETURN apoc.agg.rollup(p, $groupKeys, ['Price', 'otherNum'], {cube: true}) as data"; + testCall(db, call, map("groupKeys", List.of(CATEGORY_ID, SUPPLIER_ID, ANOTHER_ID)), r -> { + assertRollupCommon(expected, r); + }); + } + + @Test + public void testCube2() { + + List expected = getCubeTripleGroupTwo().stream() + .peek(i -> { + i.remove(sumOtherNum); + i.remove(countOtherNum); + i.remove(avgOtherNum); + }) + .collect(Collectors.toList()); + String call = "MATCH (p:Product) RETURN apoc.agg.rollup(p, $groupKeys, ['Price'], {cube: true}) as data"; + testCall(db, call, map("groupKeys", List.of(CATEGORY_ID, SUPPLIER_ID, ANOTHER_ID)), r -> { + assertRollupCommon(expected, r); + }); + } + + private void assertRollupCommon(List expected, Map r) { + List data = (List) r.get("data"); + + for (int i = 0; i < expected.size(); i++) { + String errMsg = String.format( + "Maps at index %s are not equal. \n Expected: %s, \n Actual: %s\n", + i, expected.get(i), data.get(i)); + assertMapEquals(errMsg, expected.get(i), data.get(i)); + } + } +} diff --git a/full/src/test/java/apoc/agg/RollupTestUtil.java b/full/src/test/java/apoc/agg/RollupTestUtil.java new file mode 100644 index 0000000000..97d7b74ae7 --- /dev/null +++ b/full/src/test/java/apoc/agg/RollupTestUtil.java @@ -0,0 +1,3293 @@ +package apoc.agg; + +import static apoc.agg.Rollup.NULL_ROLLUP; +import static apoc.util.MapUtil.map; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class RollupTestUtil { + public static final String CATEGORY_ID = "CategoryID"; + public static final String SUPPLIER_ID = "SupplierID"; + public static final String ANOTHER_ID = "anotherID"; + + public static final String sumOtherNum = "SUM(otherNum)"; + public static final String countOtherNum = "COUNT(otherNum)"; + public static final String avgOtherNum = "AVG(otherNum)"; + + public static final String sumPrice = "SUM(Price)"; + public static final String countPrice = "COUNT(Price)"; + public static final String avgPrice = "AVG(Price)"; + + static List getRollupTripleGroup() { + + return new ArrayList<>() { + { + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + 0L, + sumOtherNum, + 0.5, + countOtherNum, + 1L, + sumPrice, + 19L, + avgOtherNum, + 0.5, + countPrice, + 1L, + avgPrice, + 19.0)); + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + 1L, + sumOtherNum, + 0.3, + countOtherNum, + 1L, + sumPrice, + 18L, + avgOtherNum, + 0.3, + countPrice, + 1L, + avgPrice, + 18.0)); + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.8, + countOtherNum, + 2L, + sumPrice, + 37L, + avgOtherNum, + 0.4, + countPrice, + 2L, + avgPrice, + 18.5)); + add(map( + CATEGORY_ID, + 2L, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + 1L, + sumOtherNum, + 0.6, + countOtherNum, + 1L, + sumPrice, + 10L, + avgOtherNum, + 0.6, + countPrice, + 1L, + avgPrice, + 10.0)); + add(map( + CATEGORY_ID, + 2L, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.6, + countOtherNum, + 1L, + sumPrice, + 10L, + avgOtherNum, + 0.6, + countPrice, + 1L, + avgPrice, + 10.0)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 2.0999999999999996, + countOtherNum, + 4L, + sumPrice, + 65L, + avgOtherNum, + 0.5249999999999999, + countPrice, + 4L, + avgPrice, + 16.25)); + add(map( + CATEGORY_ID, + null, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + 1L, + sumOtherNum, + 0.7, + countOtherNum, + 1L, + sumPrice, + 18L, + avgOtherNum, + 0.7, + countPrice, + 1L, + avgPrice, + 18.0)); + add(map( + CATEGORY_ID, + null, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.7, + countOtherNum, + 1L, + sumPrice, + 18L, + avgOtherNum, + 0.7, + countPrice, + 1L, + avgPrice, + 18.0)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + 4L, + ANOTHER_ID, + 0L, + sumOtherNum, + 0.6, + countOtherNum, + 1L, + sumPrice, + 31L, + avgOtherNum, + 0.6, + countPrice, + 1L, + avgPrice, + 31.0)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + 4L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.6, + countOtherNum, + 1L, + sumPrice, + 31L, + avgOtherNum, + 0.6, + countPrice, + 1L, + avgPrice, + 31.0)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 4L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.6, + countOtherNum, + 1L, + sumPrice, + 31L, + avgOtherNum, + 0.6, + countPrice, + 1L, + avgPrice, + 31.0)); + add(map( + CATEGORY_ID, + 4L, + SUPPLIER_ID, + 5L, + ANOTHER_ID, + 1L, + sumOtherNum, + 0.2, + countOtherNum, + 1L, + sumPrice, + 21L, + avgOtherNum, + 0.2, + countPrice, + 1L, + avgPrice, + 21.0)); + add(map( + CATEGORY_ID, + 4L, + SUPPLIER_ID, + 5L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.2, + countOtherNum, + 1L, + sumPrice, + 21L, + avgOtherNum, + 0.2, + countPrice, + 1L, + avgPrice, + 21.0)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 5L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.2, + countOtherNum, + 1L, + sumPrice, + 21L, + avgOtherNum, + 0.2, + countPrice, + 1L, + avgPrice, + 21.0)); + add(map( + CATEGORY_ID, + 7L, + SUPPLIER_ID, + 6L, + ANOTHER_ID, + 1L, + sumOtherNum, + 0.6, + countOtherNum, + 1L, + sumPrice, + 23L, + avgOtherNum, + 0.6, + countPrice, + 1L, + avgPrice, + 23.0)); + add(map( + CATEGORY_ID, + 7L, + SUPPLIER_ID, + 6L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.6, + countOtherNum, + 1L, + sumPrice, + 23L, + avgOtherNum, + 0.6, + countPrice, + 1L, + avgPrice, + 23.0)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + 6L, + ANOTHER_ID, + 1L, + sumOtherNum, + 0.5, + countOtherNum, + 1L, + sumPrice, + 6L, + avgOtherNum, + 0.5, + countPrice, + 1L, + avgPrice, + 6.0)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + 6L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.5, + countOtherNum, + 1L, + sumPrice, + 6L, + avgOtherNum, + 0.5, + countPrice, + 1L, + avgPrice, + 6.0)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 6L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 1.1, + countOtherNum, + 2L, + sumPrice, + 29L, + avgOtherNum, + 0.55, + countPrice, + 2L, + avgPrice, + 14.5)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + 1L, + sumOtherNum, + 0.7, + countOtherNum, + 1L, + sumPrice, + 17L, + avgOtherNum, + 0.7, + countPrice, + 1L, + avgPrice, + 17.0)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.7, + countOtherNum, + 1L, + sumPrice, + 17L, + avgOtherNum, + 0.7, + countPrice, + 1L, + avgPrice, + 17.0)); + add(map( + CATEGORY_ID, + 6L, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + 1L, + sumOtherNum, + 0.8, + countOtherNum, + 1L, + sumPrice, + 39L, + avgOtherNum, + 0.8, + countPrice, + 1L, + avgPrice, + 39.0)); + add(map( + CATEGORY_ID, + 6L, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.8, + countOtherNum, + 1L, + sumPrice, + 39L, + avgOtherNum, + 0.8, + countPrice, + 1L, + avgPrice, + 39.0)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + 1L, + sumOtherNum, + 0.9, + countOtherNum, + 1L, + sumPrice, + 63L, + avgOtherNum, + 0.9, + countPrice, + 1L, + avgPrice, + 63.0)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.9, + countOtherNum, + 1L, + sumPrice, + 63L, + avgOtherNum, + 0.9, + countPrice, + 1L, + avgPrice, + 63.0)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 2.4, + countOtherNum, + 3L, + sumPrice, + 119L, + avgOtherNum, + 0.7999999999999999, + countPrice, + 3L, + avgPrice, + 39.666666666666664)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 8L, + ANOTHER_ID, + 0L, + sumOtherNum, + 0.2, + countOtherNum, + 1L, + sumPrice, + 9L, + avgOtherNum, + 0.2, + countPrice, + 1L, + avgPrice, + 9.0)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 8L, + ANOTHER_ID, + 1L, + sumOtherNum, + 0.5, + countOtherNum, + 1L, + sumPrice, + 81L, + avgOtherNum, + 0.5, + countPrice, + 1L, + avgPrice, + 81.0)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 8L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.7, + countOtherNum, + 2L, + sumPrice, + 90L, + avgOtherNum, + 0.35, + countPrice, + 2L, + avgPrice, + 45.0)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 8L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.7, + countOtherNum, + 2L, + sumPrice, + 90L, + avgOtherNum, + 0.35, + countPrice, + 2L, + avgPrice, + 45.0)); + add(map( + CATEGORY_ID, + 5L, + SUPPLIER_ID, + 9L, + ANOTHER_ID, + 0L, + sumOtherNum, + 0.9, + countOtherNum, + 1L, + sumPrice, + 9L, + avgOtherNum, + 0.9, + countPrice, + 1L, + avgPrice, + 9.0)); + add(map( + CATEGORY_ID, + 5L, + SUPPLIER_ID, + 9L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.9, + countOtherNum, + 1L, + sumPrice, + 9L, + avgOtherNum, + 0.9, + countPrice, + 1L, + avgPrice, + 9.0)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 9L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.9, + countOtherNum, + 1L, + sumPrice, + 9L, + avgOtherNum, + 0.9, + countPrice, + 1L, + avgPrice, + 9.0)); + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + 10L, + ANOTHER_ID, + 1L, + sumOtherNum, + 0.2, + countOtherNum, + 1L, + sumPrice, + 5L, + avgOtherNum, + 0.2, + countPrice, + 1L, + avgPrice, + 5.0)); + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + 10L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.2, + countOtherNum, + 1L, + sumPrice, + 5L, + avgOtherNum, + 0.2, + countPrice, + 1L, + avgPrice, + 5.0)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 10L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.2, + countOtherNum, + 1L, + sumPrice, + 5L, + avgOtherNum, + 0.2, + countPrice, + 1L, + avgPrice, + 5.0)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + 0L, + sumOtherNum, + 2L, + countOtherNum, + 1L, + sumPrice, + 31.0, + avgOtherNum, + 2.0, + countPrice, + 1L, + avgPrice, + 31.0)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + 1L, + sumOtherNum, + 0.1, + countOtherNum, + 1L, + sumPrice, + 14.0, + avgOtherNum, + 0.1, + countPrice, + 1L, + avgPrice, + 14.0)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 2.1, + countOtherNum, + 2L, + sumPrice, + 45.0, + avgOtherNum, + 1.05, + countPrice, + 2L, + avgPrice, + 22.5)); + add(map( + CATEGORY_ID, + 4L, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + 0L, + sumOtherNum, + 0.7, + countOtherNum, + 1L, + sumPrice, + 44L, + avgOtherNum, + 0.7, + countPrice, + 1L, + avgPrice, + 44.0)); + add(map( + CATEGORY_ID, + 4L, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.7, + countOtherNum, + 1L, + sumPrice, + 44L, + avgOtherNum, + 0.7, + countPrice, + 1L, + avgPrice, + 44.0)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 2.8, + countOtherNum, + 3L, + sumPrice, + 89.0, + avgOtherNum, + 0.9333333333333332, + countPrice, + 3L, + avgPrice, + 29.666666666666668)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 12.4, + countOtherNum, + 20L, + sumPrice, + 675.0, + avgOtherNum, + 0.62, + countPrice, + 20L, + avgPrice, + 33.75)); + add(map( + CATEGORY_ID, + 2L, + SUPPLIER_ID, + null, + ANOTHER_ID, + 0L, + sumOtherNum, + 0.8, + countOtherNum, + 1L, + sumPrice, + 199L, + avgOtherNum, + 0.8, + countPrice, + 1L, + avgPrice, + 199.0)); + add(map( + CATEGORY_ID, + 2L, + SUPPLIER_ID, + null, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.8, + countOtherNum, + 1L, + sumPrice, + 199L, + avgOtherNum, + 0.8, + countPrice, + 1L, + avgPrice, + 199.0)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + null, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 1.4, + countOtherNum, + 2L, + sumPrice, + 217L, + avgOtherNum, + 0.7, + countPrice, + 2L, + avgPrice, + 108.5)); + add(map( + CATEGORY_ID, + null, + SUPPLIER_ID, + null, + ANOTHER_ID, + 0L, + sumOtherNum, + 0.6, + countOtherNum, + 1L, + sumPrice, + 18L, + avgOtherNum, + 0.6, + countPrice, + 1L, + avgPrice, + 18.0)); + add(map( + CATEGORY_ID, + null, + SUPPLIER_ID, + null, + ANOTHER_ID, + NULL_ROLLUP, + sumOtherNum, + 0.6, + countOtherNum, + 1L, + sumPrice, + 18L, + avgOtherNum, + 0.6, + countPrice, + 1L, + avgPrice, + 18.0)); + } + }; + } + + static List getRollupTripleGroupTwo() { + return new ArrayList<>() { + { + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.5, + sumPrice, + 19L, + countPrice, + 1L, + sumOtherNum, + 0.5, + avgPrice, + 19.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.3, + sumPrice, + 18L, + countPrice, + 1L, + sumOtherNum, + 0.3, + avgPrice, + 18.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.4, + sumPrice, + 37L, + countPrice, + 2L, + sumOtherNum, + 0.8, + avgPrice, + 18.5, + countOtherNum, + 2L)); + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + 10L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.2, + sumPrice, + 5L, + countPrice, + 1L, + sumOtherNum, + 0.2, + avgPrice, + 5.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + 10L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.2, + sumPrice, + 5L, + countPrice, + 1L, + sumOtherNum, + 0.2, + avgPrice, + 5.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.3333333333333333, + sumPrice, + 42L, + countPrice, + 3L, + sumOtherNum, + 1.0, + avgPrice, + 14.0, + countOtherNum, + 3L)); + add(map( + CATEGORY_ID, + 2L, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.6, + sumPrice, + 10L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 10.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 2L, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.6, + sumPrice, + 10L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 10.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 2L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.7, + sumPrice, + 209L, + countPrice, + 2L, + sumOtherNum, + 1.4, + avgPrice, + 104.5, + countOtherNum, + 2L)); + add(map( + CATEGORY_ID, + 2L, + SUPPLIER_ID, + null, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.8, + sumPrice, + 199L, + countPrice, + 1L, + sumOtherNum, + 0.8, + avgPrice, + 199.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 2L, + SUPPLIER_ID, + null, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.8, + sumPrice, + 199L, + countPrice, + 1L, + sumOtherNum, + 0.8, + avgPrice, + 199.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.7, + sumPrice, + 17L, + countPrice, + 1L, + sumOtherNum, + 0.7, + avgPrice, + 17.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.7, + sumPrice, + 17L, + countPrice, + 1L, + sumOtherNum, + 0.7, + avgPrice, + 17.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 8L, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.2, + sumPrice, + 9L, + countPrice, + 1L, + sumOtherNum, + 0.2, + avgPrice, + 9.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 8L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.5, + sumPrice, + 81L, + countPrice, + 1L, + sumOtherNum, + 0.5, + avgPrice, + 81.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 8L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.35, + sumPrice, + 90L, + countPrice, + 2L, + sumOtherNum, + 0.7, + avgPrice, + 45.0, + countOtherNum, + 2L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + 0L, + avgOtherNum, + 2.0, + sumPrice, + 31.0, + countPrice, + 1L, + sumOtherNum, + 2L, + avgPrice, + 31.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.1, + sumPrice, + 14.0, + countPrice, + 1L, + sumOtherNum, + 0.1, + avgPrice, + 14.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 1.05, + sumPrice, + 45.0, + countPrice, + 2L, + sumOtherNum, + 2.1, + avgPrice, + 22.5, + countOtherNum, + 2L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.7, + sumPrice, + 152.0, + countPrice, + 5L, + sumOtherNum, + 3.5, + avgPrice, + 30.4, + countOtherNum, + 5L)); + add(map( + CATEGORY_ID, + 4L, + SUPPLIER_ID, + 5L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.2, + sumPrice, + 21L, + countPrice, + 1L, + sumOtherNum, + 0.2, + avgPrice, + 21.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 4L, + SUPPLIER_ID, + 5L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.2, + sumPrice, + 21L, + countPrice, + 1L, + sumOtherNum, + 0.2, + avgPrice, + 21.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 4L, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.7, + sumPrice, + 44L, + countPrice, + 1L, + sumOtherNum, + 0.7, + avgPrice, + 44.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 4L, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.7, + sumPrice, + 44L, + countPrice, + 1L, + sumOtherNum, + 0.7, + avgPrice, + 44.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 4L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.44999999999999996, + sumPrice, + 65L, + countPrice, + 2L, + sumOtherNum, + 0.8999999999999999, + avgPrice, + 32.5, + countOtherNum, + 2L)); + add(map( + CATEGORY_ID, + 5L, + SUPPLIER_ID, + 9L, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.9, + sumPrice, + 9L, + countPrice, + 1L, + sumOtherNum, + 0.9, + avgPrice, + 9.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 5L, + SUPPLIER_ID, + 9L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.9, + sumPrice, + 9L, + countPrice, + 1L, + sumOtherNum, + 0.9, + avgPrice, + 9.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 5L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.9, + sumPrice, + 9L, + countPrice, + 1L, + sumOtherNum, + 0.9, + avgPrice, + 9.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 6L, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.8, + sumPrice, + 39L, + countPrice, + 1L, + sumOtherNum, + 0.8, + avgPrice, + 39.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 6L, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.8, + sumPrice, + 39L, + countPrice, + 1L, + sumOtherNum, + 0.8, + avgPrice, + 39.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 6L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.8, + sumPrice, + 39L, + countPrice, + 1L, + sumOtherNum, + 0.8, + avgPrice, + 39.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 7L, + SUPPLIER_ID, + 6L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.6, + sumPrice, + 23L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 23.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 7L, + SUPPLIER_ID, + 6L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.6, + sumPrice, + 23L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 23.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 7L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.6, + sumPrice, + 23L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 23.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + 4L, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.6, + sumPrice, + 31L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 31.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + 4L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.6, + sumPrice, + 31L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 31.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + 6L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.5, + sumPrice, + 6L, + countPrice, + 1L, + sumOtherNum, + 0.5, + avgPrice, + 6.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + 6L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.5, + sumPrice, + 6L, + countPrice, + 1L, + sumOtherNum, + 0.5, + avgPrice, + 6.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.9, + sumPrice, + 63L, + countPrice, + 1L, + sumOtherNum, + 0.9, + avgPrice, + 63.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.9, + sumPrice, + 63L, + countPrice, + 1L, + sumOtherNum, + 0.9, + avgPrice, + 63.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.6666666666666666, + sumPrice, + 100L, + countPrice, + 3L, + sumOtherNum, + 2.0, + avgPrice, + 33.333333333333336, + countOtherNum, + 3L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.62, + sumPrice, + 675.0, + countPrice, + 20L, + sumOtherNum, + 12.4, + avgPrice, + 33.75, + countOtherNum, + 20L)); + add(map( + CATEGORY_ID, + null, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.7, + sumPrice, + 18L, + countPrice, + 1L, + sumOtherNum, + 0.7, + avgPrice, + 18.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + null, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.7, + sumPrice, + 18L, + countPrice, + 1L, + sumOtherNum, + 0.7, + avgPrice, + 18.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + null, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.6499999999999999, + sumPrice, + 36L, + countPrice, + 2L, + sumOtherNum, + 1.2999999999999998, + avgPrice, + 18.0, + countOtherNum, + 2L)); + add(map( + CATEGORY_ID, + null, + SUPPLIER_ID, + null, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.6, + sumPrice, + 18L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 18.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + null, + SUPPLIER_ID, + null, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.6, + sumPrice, + 18L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 18.0, + countOtherNum, + 1L)); + } + }; + } + + static List getCubeTripleGroupTwo() { + return new ArrayList<>() { + { + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.5, + sumPrice, + 19L, + countPrice, + 1L, + sumOtherNum, + 0.5, + avgPrice, + 19.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.3, + sumPrice, + 18L, + countPrice, + 1L, + sumOtherNum, + 0.3, + avgPrice, + 18.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.4, + sumPrice, + 37L, + countPrice, + 2L, + sumOtherNum, + 0.8, + avgPrice, + 18.5, + countOtherNum, + 2L)); + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + 10L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.2, + sumPrice, + 5L, + countPrice, + 1L, + sumOtherNum, + 0.2, + avgPrice, + 5.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + 10L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.2, + sumPrice, + 5L, + countPrice, + 1L, + sumOtherNum, + 0.2, + avgPrice, + 5.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.5, + sumPrice, + 19L, + countPrice, + 1L, + sumOtherNum, + 0.5, + avgPrice, + 19.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.25, + sumPrice, + 23L, + countPrice, + 2L, + sumOtherNum, + 0.5, + avgPrice, + 11.5, + countOtherNum, + 2L)); + add(map( + CATEGORY_ID, + 1L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.3333333333333333, + sumPrice, + 42L, + countPrice, + 3L, + sumOtherNum, + 1.0, + avgPrice, + 14.0, + countOtherNum, + 3L)); + add(map( + CATEGORY_ID, + 2L, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.6, + sumPrice, + 10L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 10.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 2L, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.6, + sumPrice, + 10L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 10.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 2L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.8, + sumPrice, + 398L, + countPrice, + 2L, + sumOtherNum, + 1.6, + avgPrice, + 199.0, + countOtherNum, + 2L)); + add(map( + CATEGORY_ID, + 2L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.6, + sumPrice, + 10L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 10.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 2L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.7333333333333334, + sumPrice, + 408L, + countPrice, + 3L, + sumOtherNum, + 2.2, + avgPrice, + 136.0, + countOtherNum, + 3L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.7, + sumPrice, + 17L, + countPrice, + 1L, + sumOtherNum, + 0.7, + avgPrice, + 17.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.7, + sumPrice, + 17L, + countPrice, + 1L, + sumOtherNum, + 0.7, + avgPrice, + 17.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 8L, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.2, + sumPrice, + 9L, + countPrice, + 1L, + sumOtherNum, + 0.2, + avgPrice, + 9.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 8L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.5, + sumPrice, + 81L, + countPrice, + 1L, + sumOtherNum, + 0.5, + avgPrice, + 81.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 8L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.35, + sumPrice, + 90L, + countPrice, + 2L, + sumOtherNum, + 0.7, + avgPrice, + 45.0, + countOtherNum, + 2L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + 0L, + avgOtherNum, + 2.0, + sumPrice, + 31.0, + countPrice, + 1L, + sumOtherNum, + 2L, + avgPrice, + 31.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.1, + sumPrice, + 14.0, + countPrice, + 1L, + sumOtherNum, + 0.1, + avgPrice, + 14.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 1.05, + sumPrice, + 45.0, + countPrice, + 2L, + sumOtherNum, + 2.1, + avgPrice, + 22.5, + countOtherNum, + 2L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + 0L, + avgOtherNum, + 1.1, + sumPrice, + 40.0, + countPrice, + 2L, + sumOtherNum, + 2.2, + avgPrice, + 20.0, + countOtherNum, + 2L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.43333333333333335, + sumPrice, + 112.0, + countPrice, + 3L, + sumOtherNum, + 1.3, + avgPrice, + 37.333333333333336, + countOtherNum, + 3L)); + add(map( + CATEGORY_ID, + 3L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.7, + sumPrice, + 152.0, + countPrice, + 5L, + sumOtherNum, + 3.5, + avgPrice, + 30.4, + countOtherNum, + 5L)); + add(map( + CATEGORY_ID, + 4L, + SUPPLIER_ID, + 5L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.2, + sumPrice, + 21L, + countPrice, + 1L, + sumOtherNum, + 0.2, + avgPrice, + 21.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 4L, + SUPPLIER_ID, + 5L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.2, + sumPrice, + 21L, + countPrice, + 1L, + sumOtherNum, + 0.2, + avgPrice, + 21.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 4L, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.7, + sumPrice, + 44L, + countPrice, + 1L, + sumOtherNum, + 0.7, + avgPrice, + 44.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 4L, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.7, + sumPrice, + 44L, + countPrice, + 1L, + sumOtherNum, + 0.7, + avgPrice, + 44.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 4L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.7, + sumPrice, + 44L, + countPrice, + 1L, + sumOtherNum, + 0.7, + avgPrice, + 44.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 4L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.2, + sumPrice, + 21L, + countPrice, + 1L, + sumOtherNum, + 0.2, + avgPrice, + 21.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 4L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.44999999999999996, + sumPrice, + 65L, + countPrice, + 2L, + sumOtherNum, + 0.8999999999999999, + avgPrice, + 32.5, + countOtherNum, + 2L)); + add(map( + CATEGORY_ID, + 5L, + SUPPLIER_ID, + 9L, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.9, + sumPrice, + 9L, + countPrice, + 1L, + sumOtherNum, + 0.9, + avgPrice, + 9.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 5L, + SUPPLIER_ID, + 9L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.9, + sumPrice, + 9L, + countPrice, + 1L, + sumOtherNum, + 0.9, + avgPrice, + 9.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 5L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.9, + sumPrice, + 9L, + countPrice, + 1L, + sumOtherNum, + 0.9, + avgPrice, + 9.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 5L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.9, + sumPrice, + 9L, + countPrice, + 1L, + sumOtherNum, + 0.9, + avgPrice, + 9.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 6L, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.8, + sumPrice, + 39L, + countPrice, + 1L, + sumOtherNum, + 0.8, + avgPrice, + 39.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 6L, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.8, + sumPrice, + 39L, + countPrice, + 1L, + sumOtherNum, + 0.8, + avgPrice, + 39.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 6L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.8, + sumPrice, + 39L, + countPrice, + 1L, + sumOtherNum, + 0.8, + avgPrice, + 39.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 6L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.8, + sumPrice, + 39L, + countPrice, + 1L, + sumOtherNum, + 0.8, + avgPrice, + 39.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 7L, + SUPPLIER_ID, + 6L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.6, + sumPrice, + 23L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 23.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 7L, + SUPPLIER_ID, + 6L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.6, + sumPrice, + 23L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 23.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 7L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.6, + sumPrice, + 23L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 23.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 7L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.6, + sumPrice, + 23L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 23.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + 4L, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.6, + sumPrice, + 31L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 31.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + 4L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.6, + sumPrice, + 31L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 31.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + 6L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.5, + sumPrice, + 6L, + countPrice, + 1L, + sumOtherNum, + 0.5, + avgPrice, + 6.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + 6L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.5, + sumPrice, + 6L, + countPrice, + 1L, + sumOtherNum, + 0.5, + avgPrice, + 6.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.9, + sumPrice, + 63L, + countPrice, + 1L, + sumOtherNum, + 0.9, + avgPrice, + 63.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.9, + sumPrice, + 63L, + countPrice, + 1L, + sumOtherNum, + 0.9, + avgPrice, + 63.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.6, + sumPrice, + 31L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 31.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.7, + sumPrice, + 69L, + countPrice, + 2L, + sumOtherNum, + 1.4, + avgPrice, + 34.5, + countOtherNum, + 2L)); + add(map( + CATEGORY_ID, + 8L, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.6666666666666666, + sumPrice, + 100L, + countPrice, + 3L, + sumOtherNum, + 2.0, + avgPrice, + 33.333333333333336, + countOtherNum, + 3L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.5, + sumPrice, + 19L, + countPrice, + 1L, + sumOtherNum, + 0.5, + avgPrice, + 19.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.575, + sumPrice, + 64L, + countPrice, + 4L, + sumOtherNum, + 2.3, + avgPrice, + 16.0, + countOtherNum, + 4L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 1L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.5599999999999999, + sumPrice, + 83L, + countPrice, + 5L, + sumOtherNum, + 2.8, + avgPrice, + 16.6, + countOtherNum, + 5L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 4L, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.6, + sumPrice, + 31L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 31.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 4L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.6, + sumPrice, + 31L, + countPrice, + 1L, + sumOtherNum, + 0.6, + avgPrice, + 31.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 5L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.2, + sumPrice, + 21L, + countPrice, + 1L, + sumOtherNum, + 0.2, + avgPrice, + 21.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 5L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.2, + sumPrice, + 21L, + countPrice, + 1L, + sumOtherNum, + 0.2, + avgPrice, + 21.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 6L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.55, + sumPrice, + 29L, + countPrice, + 2L, + sumOtherNum, + 1.1, + avgPrice, + 14.5, + countOtherNum, + 2L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 6L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.55, + sumPrice, + 29L, + countPrice, + 2L, + sumOtherNum, + 1.1, + avgPrice, + 14.5, + countOtherNum, + 2L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.7999999999999999, + sumPrice, + 119L, + countPrice, + 3L, + sumOtherNum, + 2.4, + avgPrice, + 39.666666666666664, + countOtherNum, + 3L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 7L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.7999999999999999, + sumPrice, + 119L, + countPrice, + 3L, + sumOtherNum, + 2.4, + avgPrice, + 39.666666666666664, + countOtherNum, + 3L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 8L, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.2, + sumPrice, + 9L, + countPrice, + 1L, + sumOtherNum, + 0.2, + avgPrice, + 9.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 8L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.5, + sumPrice, + 81L, + countPrice, + 1L, + sumOtherNum, + 0.5, + avgPrice, + 81.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 8L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.35, + sumPrice, + 90L, + countPrice, + 2L, + sumOtherNum, + 0.7, + avgPrice, + 45.0, + countOtherNum, + 2L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 9L, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.9, + sumPrice, + 9L, + countPrice, + 1L, + sumOtherNum, + 0.9, + avgPrice, + 9.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 9L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.9, + sumPrice, + 9L, + countPrice, + 1L, + sumOtherNum, + 0.9, + avgPrice, + 9.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 10L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.2, + sumPrice, + 5L, + countPrice, + 1L, + sumOtherNum, + 0.2, + avgPrice, + 5.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 10L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.2, + sumPrice, + 5L, + countPrice, + 1L, + sumOtherNum, + 0.2, + avgPrice, + 5.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + 0L, + avgOtherNum, + 1.35, + sumPrice, + 75.0, + countPrice, + 2L, + sumOtherNum, + 2.7, + avgPrice, + 37.5, + countOtherNum, + 2L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.1, + sumPrice, + 14.0, + countPrice, + 1L, + sumOtherNum, + 0.1, + avgPrice, + 14.0, + countOtherNum, + 1L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + 11L, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.9333333333333332, + sumPrice, + 89.0, + countPrice, + 3L, + sumOtherNum, + 2.8, + avgPrice, + 29.666666666666668, + countOtherNum, + 3L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + 0L, + avgOtherNum, + 0.7416666666666667, + sumPrice, + 613.0, + countPrice, + 12L, + sumOtherNum, + 8.9, + avgPrice, + 51.083333333333336, + countOtherNum, + 12L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + 1L, + avgOtherNum, + 0.5230769230769231, + sumPrice, + 333.0, + countPrice, + 13L, + sumOtherNum, + 6.8, + avgPrice, + 25.615384615384617, + countOtherNum, + 13L)); + add(map( + CATEGORY_ID, + NULL_ROLLUP, + SUPPLIER_ID, + NULL_ROLLUP, + ANOTHER_ID, + NULL_ROLLUP, + avgOtherNum, + 0.628, + sumPrice, + 946.0, + countPrice, + 25L, + sumOtherNum, + 15.7, + avgPrice, + 37.84, + countOtherNum, + 25L)); + } + }; + } +}