多阵列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] │
└─────────────────────────────────┘
根据此掩码过滤未完成的商店:
请注意 shops
和 accumulatedNeed
的大小必须相等。
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
过滤额外的行。
问题: 计算由同一行上的另一个数组过滤的数组中的不同值(并且聚合更高)。
解释:
使用此数据:
也可能是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] │
└─────────────────────────────────┘
根据此掩码过滤未完成的商店:
请注意 shops
和 accumulatedNeed
的大小必须相等。
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
过滤额外的行。