【发布时间】: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。
这个问题类似于
根据上述情况,我认为原因是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 来划分逻辑。
标签: sql snowflake-cloud-data-platform