【问题标题】:Multiple arrays Clickhouse多阵列 Clickhouse
【发布时间】:2021-03-18 14:46:44
【问题描述】:

问题: 计算由同一行上的另一个数组过滤的数组中的不同值(并且 agg 更高)。

解释: 使用这些数据: 在尺寸 D70 中,有 5 件可用(hqsize),但商店要求 15 件。通过使用累积需要列,列商店中的前 5 家商店应该收到物品(因为每个商店都要求 1 件)。即 [4098,4101,4109,4076,4080]。

accumulatedNeed 中的值也可能是 [1,4,5,5,5,...,15],其中商店 1 请求 1 件,商店 2 请求 3 件等。那么只有 3 家商店会得到。

E75尺码有足够的存货,所以每家店都会收到(10家店):

现在我想要 D70 和 E75 的不同商店列表,这将是最终结果: [4098,4101,4109,4076,4080,4062,4063,4067,4072,4075,4056,4058,4059,4061](14 个独立商店)(4109 只计算一次)

想要的结果: [4098,4101,4109,4076,4080,4062,4063,4067,4072,4075,4056,4058,4059,4061]。 (14 家独特的商店) 如果更好的话,我完全愿意构建数据。 之所以不能预先计算,是因为结果取决于过滤了哪些店铺。

其他问题 下面来自 Vdimir 的答案很好,我已将其用作最终解决方案的基础,但该解决方案并未涵盖(部分完成)。 如果库存号在 runningNeed 数组中,我们都可以,但剩余的则不处理。

If you got:
 select 5 as stock,[2,2,3,3] as need, [1,2,3,4] as shops, arrayCumSum(need) as runningNeed,arrayMap(x -> (x <= stock), runningNeed) as mask

你会得到:

这是不正确的,因为第 3 家商店应该有 1 个库存 (5-2-2 = 1) 我似乎无法理解如何使用“给定股票”制作一个数组,在本例中为 [2,2,1,0]

【问题讨论】:

    标签: clickhouse


    【解决方案1】:

    我使用此查询来创建包含与您的屏幕截图类似的数据的表:

    CREATE TABLE t
    (
        Size String,
        hqsize Int,
        accumulatedNeed Array(Int),
        shops Array(Int)
    ) engine = Memory;
    
    INSERT INTO t VALUES ('D70', 5, [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], [4098,4101,4109,4076,4080,4083,4062,4063,4067,4072,4075,4056,4057,4058,4059]),('E75', 43, [1,2,3,4,5,6,7,8,9,10], [4109,4062,4063,4067,4072,4075,4056,4058,4059,4061]);
    

    找出哪些商店可以收到足够的物品:

    SELECT arrayMap(x -> (x <= hqsize), accumulatedNeed) as mask FROM t;
    
    ┌─mask────────────────────────────┐
    │ [1,1,1,1,1,0,0,0,0,0,0,0,0,0,0] │
    │ [1,1,1,1,1,1,1,1,1,1]           │
    └─────────────────────────────────┘
    

    根据此掩码过滤未完成的商店: 请注意,shopsaccumulatedNeed 的大小必须相等。

    SELECT arrayFilter((x,y) -> y, shops, mask) as fulfilled_shops, arrayMap(x -> (x <= hqsize), accumulatedNeed) as mask FROM t;
    
    ┌─fulfilled_shops─────────────────────────────────────┬─mask────────────────────────────┐
    │ [4098,4101,4109,4076,4080]                          │ [1,1,1,1,1,0,0,0,0,0,0,0,0,0,0] │
    │ [4109,4062,4063,4067,4072,4075,4056,4058,4059,4061] │ [1,1,1,1,1,1,1,1,1,1]           │
    └─────────────────────────────────────────────────────┴─────────────────────────────────┘
    

    然后您可以创建包含所有不同商店的表:

    SELECT DISTINCT arrayJoin(fulfilled_shops) as shops FROM (
        SELECT arrayMap(x -> (x <= hqsize), accumulatedNeed) as mask, arrayFilter((x,y) -> y, shops, mask) as fulfilled_shops FROM t
    );
    
    ┌─shops─┐
    │  4098 │
    │  4101 │
    │  4109 │
    │  4076 │
    │  4080 │
    │  4062 │
    │  4063 │
    │  4067 │
    │  4072 │
    │  4075 │
    │  4056 │
    │  4058 │
    │  4059 │
    │  4061 │
    └───────┘
    
    14 rows in set. Elapsed: 0.049 sec.
    

    或者如果您需要单个数组将其分组:

    SELECT groupArrayDistinct(arrayJoin(fulfilled_shops)) as shops FROM (
        SELECT arrayMap(x -> (x <= hqsize), accumulatedNeed) as mask, arrayFilter((x,y) -> y, shops, mask) as fulfilled_shops FROM t
    );
    
    ┌─shops───────────────────────────────────────────────────────────────────┐
    │ [4080,4076,4101,4075,4056,4061,4062,4063,4109,4058,4067,4059,4072,4098] │
    └─────────────────────────────────────────────────────────────────────────┘
    

    如果您只需要来自 D70 和 E75 的数据,您可以在之前使用 WHERE 过滤表中的额外行。

    【讨论】:

    • 我正在伸出援手,因为我卡住了:/。请参阅我的附加问题评论。期待回复
    猜你喜欢
    • 2020-03-23
    • 2021-12-11
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 2016-05-24
    • 2021-10-05
    • 1970-01-01
    • 2017-10-23
    相关资源
    最近更新 更多