【问题标题】:SQL window function is grouped, but still get "must be an aggregate expression or appear in GROUP BY clause"SQL窗口函数被分组,但仍然得到“必须是聚合表达式或出现在GROUP BY子句中”
【发布时间】:2021-06-10 21:07:26
【问题描述】:

我有一个 SQL (presto) 查询,假设是这样的:

select
      id
    , product_name
    , product_type
    , sum(sales) as total_sales
    , sum(sales) over (partition by type) as sales_by_type

from some_table

group by 1,2,3

当我运行它时,我收到一条错误消息,告诉我窗口函数需要出现在 GROUP BY 子句中。用子查询解决这个问题的最佳解决方案是什么?或者我需要进行一些语法更改才能使其正常工作?

【问题讨论】:

  • 您按前三个字段分组,然后计算聚合和窗口函数。窗口函数不是分组操作,所以这就是它失败的原因。你想达到什么目的。如果你把它拼出来,建议解决方案会更容易
  • 谢谢@MartinTraverso -- 我想我的问题是在同一个选择语句中是否可以有一个聚合和一个窗口函数。
  • 你可以,但这取决于你想要做什么。从逻辑上讲,首先评估聚合/分组,然后将窗口函数应用于结果。例如,您可以有以下形状的查询:SELECT first_value(sum(c)) OVER (PARTITION BY b) FROM t GROUP BY a, b,相当于SELECT first_value(x) OVER (PARTITION BY b) FROM (SELECT a, b, sum(c) AS x FROM t GROUP BY a, b)

标签: sql presto trino


【解决方案1】:

你需要的是下面的东西

select
      id
    , product_name
    , product_type
    , sum(sales) over () as total_sales
    , sum(sales) over (partition by type) as sales_by_type
    from some_table

select
      id
    , product_name
    , product_type
    , sum(sales) over (partition by (select 1)) as total_sales
    , sum(sales) over (partition by type) as sales_by_type
    from some_table

这两种方法都可以在 sql server 中使用。不确定什么/是否适用于 presto。

我也看到了下面的变化。

over (partition by null)

【讨论】:

  • OVER () 是 Presto / Trino 的惯用方式。
【解决方案2】:

如果您想要该类型的总销售额,则需要嵌套sum()s:

select id, product_name, product_type,
       sum(sales) as total_sales,
       sum(sum(sales)) over (partition by type) as sales_by_type
from some_table
group by 1,2,3;

如果您还想要所有销售额的总和,那么:

select id, product_name, product_type,
       sum(sales) as total_sales,
       sum(sum(sales)) over (partition by type) as sales_by_type,
       sum(sum(sales)) over () as total_total_sales
from some_table
group by 1,2,3;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-14
    • 1970-01-01
    • 2013-11-05
    • 2019-10-16
    • 1970-01-01
    • 1970-01-01
    • 2013-08-06
    相关资源
    最近更新 更多