有没有办法在 Trino/Presto 中通过按键过滤和排序地图?

问题描述 投票:0回答:1

有没有一种方法可以通过键过滤一个映射,然后对键值对的结果映射进行键排序?现在我使用了 map_keys 函数,它只给我键数组,并使用 array_sort 对键进行排序,并应用过滤函数来摆脱我不关心的键,但事实证明我没有简单的方法来获得按顺序与那些排序键相对应的值,最终我想要唯一值组合,所以我有一个像

approx_distinct(resultMap)
这样的函数。只是为了澄清我只希望 k=v 按键排序。

这是我所拥有的:

array_sort(filter(map_keys(mapColumn), 
x -> x not in ('p', 'q')))

现在我想我可以使用排序后的键并从原始 mapColumn 中获取它们对应的值,但我不知道这是否是正确的方法。

任何帮助表示赞赏。谢谢!

更新: 我在这里发布源表和结果表,因为我采用的方法可能不是最好的,所以感谢任何将下表转换为结果表的帮助。

我的过滤器 地图专栏
A {x=1, z=2, y=3, p=4, q=5}
A {z=1, y=2, x=1, p=4, q=5}
A {y=2, x=2, z=3, p=4, q=5}

现在我想要一个结果映射,它只包含不是 p 和 q 的键,但按该行中剩余键的其余部分排序,结果如下:

我的过滤器 地图专栏
A {x=1, y=3, z=2}
A {x=1, y=2, z=1}
A {x=2, y=2, z=3}

最终我想接受它并应用 approx_distinct 我得到所有唯一的值组合,我的地图键被排序所以我得到 {1,3,2},{1,2,1},{2,2,3} = 3

sql presto trino
1个回答
0
投票

不,默认情况下 map 是无序数据结构(如果你需要一个有序的数据结构 - 你需要 orderd map 这将牺牲一些性能和/或内存来满足所需的保证并且 AFAIK 在 Presto/Trino 中不存在),所以即使您能够按需要的顺序对地图进行排序和重新组合,我也建议您不要依赖这种行为。

但事实证明我没有简单的方法来按顺序获取这些排序键的值。

在没有看到实际数据和所需输出的情况下,很难提出建议,但是如果您有一组有序的键,那么获取有序值不是一个大问题,只需使用

transform
并按键从地图中选择:

select transform(
    array_sort(map_keys(m)), -- sorted keys
    k -> m[k]) values_sorted_by_key
from (values (map(array[2, 1], array['b', 'a']))) as t(m);

输出:

 values_sorted_by_key
----------------------
 [a, b]
(1 row)

更新

首先我怀疑 `` 或其他函数关心映射中键的顺序:

select map(array[2,1], array['b', 'a']) = map(array[1,2], array['a', 'b']);

输出:

 _col0
-------
 true
select approx_distinct(m)
from (values (map(array[2,1], array['b', 'a'])),
             (map(array[1,2], array['a', 'b'])),
             (map(array[2,1], array['b', 'a1']))) as t(m)
group by true;

输出:

 _col0
-------
     2

我还建议考虑使用

row
而不是 map(如果你没有太多要分析的键),这可能会使一切变得更容易:

select approx_distinct((m[1], m[2])) -- use element_at if key can be missing from map
from (values (map(array[2,1,3], array['b', 'a', '-'])),
             (map(array[1,2,3], array['a', 'b', '-'])),
             (map(array[2,1,3], array['b', 'a1', '-']))) as t(m)
group by true
;
© www.soinside.com 2019 - 2024. All rights reserved.