我有一张桌子
Name pets
--------------
Andy {dog:2, cat:1, bird:4}
John {tiger:3, elephant:1, fish:2}
Mary {dog:2, pig:2}
Run Code Online (Sandbox Code Playgroud)
我想要为每个人找到最大数量的宠物类型。如果出现平局,请为每只宠物复制一行。结果应如下所示:
Name max_pet
------------------
Andy bird
John tiger
Mary dog
Mary pig
Run Code Online (Sandbox Code Playgroud)
目前,我导出了表格并在 python 中完成。但我想知道我可以使用 Presto/SQL 查询来实现这一点吗?谢谢!
有几种方法可以做到这一点。一种方法是使用UNNEST将映射转换为行,每个映射条目一行。然后,您可以使用rank()窗口函数为每个名称的宠物分配排名,然后您只选择排名最高的项目。
WITH people (name, pets) AS (
VALUES
('Andy', map_from_entries(array[('dog', 2), ('cat', 1), ('bird', 4)])),
('John', map_from_entries(array[('tiger', 3), ('elephant', 1), ('fish', 2)])),
('Mary', map_from_entries(array[('dog', 2), ('pig', 2)]))
)
SELECT name, pet AS max_pet
FROM (
SELECT name, pet, count,
rank() OVER (PARTITION BY name ORDER BY count DESC) rnk
FROM people
CROSS JOIN UNNEST(pets) AS t (pet, count)
)
WHERE rnk = 1;
Run Code Online (Sandbox Code Playgroud)
name | max_pet
------+---------
Andy | bird
John | tiger
Mary | dog
Mary | pig
(4 rows)
Run Code Online (Sandbox Code Playgroud)
使用UNNEST很容易理解,但如果您需要将其与其他操作结合使用,或者您有重复的名称,则效果不佳。
另一种方法是使用 将地图转换为数组map_entries(),用于filter()选择计数等于最大计数transform()的宠物,然后使用仅返回宠物名称。在这一点上,你有一个最大宠物的数组。然后UNNEST,您可以将其分成多行,或将其保留为数组以供进一步处理。filter()并transform()使用lambda 表达式,它是 SQL 的 Presto 特定扩展。
name | max_pet
------+---------
Andy | bird
John | tiger
Mary | dog
Mary | pig
(4 rows)
Run Code Online (Sandbox Code Playgroud)
name | max_pets
------+------------
Andy | [bird]
John | [tiger]
Mary | [dog, pig]
(3 rows)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1492 次 |
| 最近记录: |