Postgresql 为什么聚合函数不能与DISTINCT ON(…)一起使用?

Postgresql 为什么聚合函数不能与DISTINCT ON(…)一起使用?,postgresql,aggregate-functions,Postgresql,Aggregate Functions,问题是: 如何获取聚合函数选择的行 这个问题,部分解决了我的问题。但我仍然无法用上的DISTINCT替换GROUP BY,原因如下: 我需要两者: 选择聚合行的id(可以使用DISTINCT ON解析) 求比率列的总和(可通过分组依据解决) 用户消耗了部分资源量。第10天的一部分用户消耗了8第10天的另一部分用户消耗了3,第4小时他不消耗资源。任务是按最大值对消耗的资源进行计费,并且在未消耗资源时不计费 id | name | amount | ratio ----+------+-----

问题是:

如何获取聚合函数选择的行

这个问题,部分解决了我的问题。但我仍然无法用上的DISTINCT替换
GROUP BY
,原因如下:

我需要两者:

  • 选择聚合行的
    id
    (可以使用
    DISTINCT ON
    解析)
  • 比率
    列的总和(可通过
    分组依据
    解决)
  • 用户消耗了部分
    资源量
    。第10天的一部分用户消耗了
    8
    第10天的另一部分用户消耗了
    3
    ,第4小时他不消耗资源。任务是按最大值对消耗的资源进行计费,并且在未消耗资源时不计费

     id | name | amount | ratio 
    ----+------+--------+-------
      1 | a    |      8 |    10
      2 | a    |      3 |    10
    
    我通过下一个查询完成此任务:

    SELECT 
        (
           SELECT id FROM t2 
           WHERE id = ANY ( ARRAY_AGG( tf.id ) ) AND amount = MAX( tf.amount ) 
        ) id,
        name, 
        MAX(amount) ma,
        SUM( ratio )
    FROM t2  tf
    GROUP BY name
    
    为什么不允许将聚合函数与
    不同的ON一起使用?

    select distinct on ( name ) id, name, amount, sum( ratio )
    from t2
    order by name, amount desc
    
    或者更简单:

    select distinct on ( name ) id, name, max(amount), sum( ratio )
    from t2
    
    这也将解决按订购的问题。不需要

    是否存在不允许上一个示例中的查询按所述工作的技术原因?

    select distinct on ( name ) id, name, amount, sum( ratio )
    from t2
    order by name, amount desc
    
    UPD
    理论上,这可以像下一步一样工作:

    第一个例子:

    select distinct on ( name ) id, name, amount, sum( ratio )
    from t2
    order by name, amount desc
    
    当找到第一个不同的行时,它保存其
    id
    name

    下次发现第二行和下一行不明显时,它将调用
    sum
    并累加
    ratio

    第二个例子:

    select distinct on ( name ) id, name, max(amount), sum( ratio )
    from t2
    
    当找到第一个不同的行时,它保存其
    id
    name
    ,累加
    ratio
    ,并将
    ratio
    的当前值设置为最大值

    下次发现第二行和下一行不明显时,它将调用
    sum
    并累加
    ratio

    如果第二行和/或下一行中任何一行的
    比率
    列的值较大,则将其保存为最大值,并更新
    id
    的保存值

    UPD
    如果
    有多行,其中amount=max(amount)
    Postgres可以从任意一行返回值。因为这是针对任何不在DISTINCT ON下的字段执行的


    为了确定返回的查询可能由
    orderby
    子句限定。这样做了

    我不确定是否完全理解了您的问题(我不理解“10h用户”部分)

    但我相信你在寻找。我将另一个问题的范围扩大了一点,并借助这样一个窗口函数添加了您的
    SUM(ratio)

    这是你期望的吗

    当然,您也可以使用相同的窗口函数计算
    MAX(amount)

    SELECT 
        id, 
        name, 
        max_amount, 
        sum_ratio 
    FROM (
        SELECT 
            t.*,
            MAX(amount) OVER w as max_amount,
            SUM(ratio) OVER w as sum_ratio
        FROM test t
        WINDOW w as (PARTITION BY name)
        ORDER BY name
    ) s 
    WHERE amount = max_amount
    

    不需要
    分组方式
    。好的,但是在这种情况下,您需要一个额外的子查询,您必须过滤窗口函数的结果(
    amount=max\u amount

    回答我的问题:

    是否存在不允许上一个示例中的查询按所述工作的技术原因

    如果有一行以上的代码,我们必须考虑如何提取ID。 对于此数据,上面的查询将生成错误:

    ERROR:  more than one row returned by a subquery used as an expression
    

    伟大的非常感谢。这解决了我的问题,但这不是这个问题的答案:WhyWhy:因为在你的例子中,你没有告诉你的分组框架是什么。也许您可以想象这样一种情况:您希望按X列分组(求和、平均值、最大值等等),但需要将Y列区分开来。所以有必要给出分组列。嗯。。。此查询未选择正确的
    id
    。它从当前帧中选择任何一行
    id
    ,但不精确地选择最大
    amount
    原因:对于这个简单的案例,分组帧与distinct相同on@EugenKonkov不,不是真的。它只是为了可视化(好的,编辑后忘了删除它,现在已经晚了;)。要将
    分组替换为
    不同的
    ERROR:  more than one row returned by a subquery used as an expression