如何在Trino/Presto中使用指定数组过滤Map中的指定键?
解决Map列按指定数组过滤键的问题
首先说下你当前SQL的问题:你用CTE生成的temp.myFiltered是单一行的数组,但主查询里没有将myTable和temp做关联,这样要么会报关联错误,要么会产生笛卡尔积,导致结果完全不符合预期。
下面给你两种靠谱的实现方式,根据需求选择:
方式一:直接用map_filter结合条件判断
如果你的保留键是排除指定键后的集合(也就是你原SQL里排除id、image的逻辑),不用单独生成数组,直接在map_filter的lambda表达式里写排除条件即可,简单高效:
SELECT map_filter(mapColumn, (k, v) -> k NOT IN ('id', 'image')) AS filtered_map FROM myTable WHERE myFilter = 'a'
如果保留键是固定的数组(比如提前确定要保留name、age这类键),可以用array_contains判断键是否在目标数组中:
SELECT map_filter(mapColumn, (k, v) -> array_contains(ARRAY['name', 'age'], k)) AS filtered_map FROM myTable WHERE myFilter = 'a'
方式二:生成排序后的键数组再构造有序Map
如果你需要最终的Map键是排序后的,用map_from_arrays结合array_sort和filter实现,能保证输出的Map键有序:
SELECT map_from_arrays( -- 生成排序后的保留键数组 array_sort(filter(map_keys(mapColumn), x -> x NOT IN ('id', 'image'))), -- 对应生成排序后键的值数组 array( SELECT element_at(mapColumn, k) FROM unnest(array_sort(filter(map_keys(mapColumn), x -> x NOT IN ('id', 'image')))) AS k ) ) AS sorted_filtered_map FROM myTable WHERE myFilter = 'a'
另外补充下element_at的作用:这个函数是根据键取Map对应的单个值,没法直接用来过滤整个Map,所以过滤Map还是得用map_filter或者上面的map_from_arrays方法。
内容的提问来源于stack exchange,提问作者arjunj
相关产品推荐
相关产品推荐

