在雪花中结合 OBJECT_AGG 和 GROUP BY

Posted

技术标签:

【中文标题】在雪花中结合 OBJECT_AGG 和 GROUP BY【英文标题】:Combining OBJECT_AGG and GROUP BY in Snowflake 【发布时间】:2021-09-07 16:46:59 【问题描述】:

有没有办法将雪花中的GROUP BYOBJECT_AGG 与两者之间的不同聚合级别结合起来?

在以下示例中,对于每个城市,我们希望返回一个对象映射 cuisine 到该城市该美食的最高米其林星级:

City Restaurant Cuisine Michelin Stars
San Fransisco Quince Californian 3
San Fransisco Coi Californian 2
San Fransisco Mister Jius Chinese 1
London Le Gavroche French 2
London La Dame de Pic French 2
London Restaurant Gordon Ramsay French 3

我们想要生成以下内容:

City Cuisine to Top Rating
San Fransisco 'Californian': 3, 'Chinese': 1
London 'French': 3

我最初的做法是:

SELECT
city,
OBJECT_AGG(cuisine, MAX(michelin_stars)::variant) over (partition by cuisine)
FROM
top_restaurants
GROUP BY city

这会返回错误cuisine is not a valid group by expression

这个问题类似于

Snowflake: "SQL compilation error:... is not a valid group by expression"

根据上述情况,我认为原因是GROUP BYPARTITION BY 之前计算,并且在GROUP BY 在尝试聚合时下降cuisine 时中断。

参考资料:

https://docs.snowflake.com/en/sql-reference/functions/object_agg.html

【问题讨论】:

如果我理解正确,您可以先使用 CTE 进行聚合,然后从该 CTE 结果创建一个对象。但是,根据您的查询,您不想将美食包括在您的组中吗?这行得通吗? 是的,我相信这可以通过首先对城市和美食进行 GROUP BY 的 CTE 来完成,两者都获得最高的米其林星,然后再次按城市滚动。但我希望能够在一个查询中干净地做到这一点! :) 虽然通常最好在没有嵌套的情况下在单个查询中编写 sql,但在某些情况下,例如这种情况,我个人甚至不会尝试这样做,因为这会使代码难以理解和维护.当查询过于复杂时,我建议使用 CTE 来划分逻辑。 【参考方案1】:

感谢操作顺序,您仍然可以在一个select 中完成。您只需先聚合citycuisine。当window function 发光时,您按city 进行分区。显然这会导致重复,因为window function 只是将计算应用于group by 留下的结果集而不折叠任何行。添加distinct,您就可以开始了

select distinct 
       city,
       object_agg(cuisine, max(michelin_stars)::variant) over (partition by city)
from t
group by city, cuisine;

【讨论】:

【参考方案2】:

我认为原因是 GROUP BY 在 PARTITION BY 之前计算,并且在 GROUP BY 在尝试聚合时丢弃美食时中断。

这正是发生的事情。

相关:A Beginner’s Guide to the True Order of SQL Operations


替代方法:

WITH cte AS (
   SELECT *
   FROM top_restaurants
   QUALIFY ROW_NUMBER() OVER(PARTITION BY city,cuisine 
                             ORDER BY michelin_stars DESC) = 1
)
SELECT city,
       OBJECT_AGG(cuisine, michelin_stars::variant)
FROM cte
GROUP BY city

【讨论】:

以上是关于在雪花中结合 OBJECT_AGG 和 GROUP BY的主要内容,如果未能解决你的问题,请参考以下文章

SpringCloud第二季之Nacos,Sentinel,Seata以及雪花算法学习笔记

SpringCloud第二季之Nacos,Sentinel,Seata以及雪花算法学习笔记

与 GROUP BY 结合的第一条记录

高可用FastDFS多Group多Storage多Tracker主备结合SpringBoot

如何在 MS SQL 中将 last_value 与 group by 结合使用?

SQL重复记录查询-count与group by having结合查询重复记录