在使用CoPPer按几个列值分组时,如何在列上进行汇总?

时间:2018-06-29 08:58:00

标签: aggregation olap cube activepivot

我有一个包含某些产品当前库存的数据集:

+--------------+-------+
| Product      | Stock |
+--------------+-------+
| chocolate    |   300 |
| coal         |    70 |
| orange juice |   400 |
+--------------+-------+

以及当月和下个月在另一数据集中的每种产品的销售额:

+--------------+------+-------+-------+
| Product      | Year | Month | Sales |
+--------------+------+-------+-------+
| chocolate    | 2017 |    05 |    55 |
| chocolate    | 2017 |    04 |   250 |
| chocolate    | 2016 |    05 |    70 |
| chocolate    | 2016 |    04 |   200 |
|     |        |   |  |     | |     | |
| coal         | 2017 |    05 |    40 |
| coal         | 2017 |    04 |    30 |
| coal         | 2016 |    05 |    50 |
| coal         | 2016 |    04 |    20 |
|     |        |   |  |     | |     | |
| orange juice | 2017 |    05 |   400 |
| orange juice | 2017 |    04 |   350 |
| orange juice | 2016 |    05 |   400 |
| orange juice | 2016 |    04 |   300 |
+--------------+--------------+-------+

我想通过使用以下公式计算当月和下个月的预期销售额来计算下个月需要订购的库存:

ExpectedSales = max(salesMaxCurrentMonth) + max(salesMaxNextMonth)

订单将是

Orders = ExpectedSales * (1 + margin) - Stock

例如,保证金为10%。

我尝试使用GroupBy按几列进行分组,如下所示,但是它似乎是按Stock而不是Product进行汇总的:

salesDataset
    .groupBy(Columns.col("Month"), Columns.col(“Product”))
    .agg(Columns.max(“Sales”).as(“SalesMaxPerMonth”))
    .agg(Columns.sum(“SalesMaxPerMonth”).as(SalesPeriod))
    .withColumn(
        “SalesExpected”, 
        Columns.col(“SalesPeriod”).multiply(Columns.literal(1 + margin)))
    .withColumn(
        “Orders”,
        Columns.col(“SalesExpected”).minus(Columns.col(“Stock”)))
    .withColumn(
        “Orders”,
        Columns.col(“Orders”).map((Double a) -> a >= 0 ? a: 0))
    .doNotAggregateAbove()
    .toCellSet()
    .show();

1 个答案:

答案 0 :(得分:2)

就聚合而言,您的逻辑是正确的,但是还有另一种构建CellSet的方法,您可以在其中提供一张地图来描述生成查询的查询的位置。

salesDataset
    .groupBy(Columns.col("Month"), Columns.col(“Product”))
    .agg(Columns.max(“Sales”).as(“SalesMaxPerMonth”))
    .agg(Columns.sum(“SalesMaxPerMonth”).as(SalesPeriod))
    .withColumn(
        “SalesExpected”, 
        Columns.col(“SalesPeriod”).multiply(Columns.literal(1 + margin)))
    .withColumn(“Orders”, Columns.col(“SalesExpected”).minus(Columns.col(“Stock”)))
    .withColumn(“Orders”, Columns.col(“Orders”).map((Double a) -> a >= 0 ? a: 0))
    .doNotAggregateAbove()
    .toCellSet(
        Empty.<String, Object>map()
        .put(“Product”,null)
        .put(“Stock”, null))
    .show();

位置null代表通配符*