多阵列Clickhouse

Multiple arrays Clickhouse

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

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

也可能是accumulatedNeed中的值为[1,4,5,5,5,...,15],其中shop 1要求1个,shop2 3个,等等。那么只有3个商店会得到。

E75尺码库存充足,所以每家店都会收到(10家店):

现在我想要 D70 和 E75 的不同商店列表,这将是最终结果: [4098,4101,4109,4076,4080,4062,4063,4067,4072,4075,4056,4058,4059,4061] (14 unique stores) (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]

我使用此查询创建 table 数据类似于您的屏幕截图:

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]           │
└─────────────────────────────────────────────────────┴─────────────────────────────────┘

然后您可以创建 table 所有不同的商店:

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 的数据,您可以在 table 之前用 WHERE 过滤额外的行。