在雪花中结合 OBJECT_AGG 和 GROUP BY
Posted
技术标签:
【中文标题】在雪花中结合 OBJECT_AGG 和 GROUP BY【英文标题】:Combining OBJECT_AGG and GROUP BY in Snowflake 【发布时间】:2021-09-07 16:46:59 【问题描述】:有没有办法将雪花中的GROUP BY
和OBJECT_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 BY
在PARTITION BY
之前计算,并且在GROUP BY
在尝试聚合时下降cuisine
时中断。
参考资料:
https://docs.snowflake.com/en/sql-reference/functions/object_agg.html
【问题讨论】:
如果我理解正确,您可以先使用 CTE 进行聚合,然后从该 CTE 结果创建一个对象。但是,根据您的查询,您不想将美食包括在您的组中吗?这行得通吗? 是的,我相信这可以通过首先对城市和美食进行 GROUP BY 的 CTE 来完成,两者都获得最高的米其林星,然后再次按城市滚动。但我希望能够在一个查询中干净地做到这一点! :) 虽然通常最好在没有嵌套的情况下在单个查询中编写 sql,但在某些情况下,例如这种情况,我个人甚至不会尝试这样做,因为这会使代码难以理解和维护.当查询过于复杂时,我建议使用 CTE 来划分逻辑。 【参考方案1】:感谢操作顺序,您仍然可以在一个select
中完成。您只需先聚合city
和cuisine
。当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以及雪花算法学习笔记
高可用FastDFS多Group多Storage多Tracker主备结合SpringBoot