代码之家  ›  专栏  ›  技术社区  ›  Eugen Konkov

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

  •  0
  • Eugen Konkov  · 技术社区  · 6 年前

    问题 was answered GROUP BY 具有 DISTINCT ON 因为下一个原因:

    我需要两者:

    1. 选择 id 不同于 )
    2. ratio 列(可以用 )

    amount 的资源被用户消耗。一天中的一部分10h用户消耗 8 第10天用户消费的另一部分 3 他不消耗资源。任务是按消耗的资源的最大值计费,并且在未消耗资源时不计费

     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
    

    为什么不允许将聚合函数用于 不同于

    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
    

    ORDER BY . 不需要了 workaround with subquery

    升级版

    第一个例子:

    在(名称)id、name、amount、sum(比率)上选择distinct
    按名称、金额说明订购
    

    当找到第一个不同的行时,它将保存其 身份证件 name

    下次当找到第二个和下一个非不同行时,它将调用 sum 积累

    第二个例子:

    选择distinct on(名称)id、name、max(金额)、sum(比率)
    从t2开始
    

    当找到第一个不同的行时,它将保存其 名称 比率 设置当前值 比率 作为最大值

    下次当找到第二个和下一个非不同行时,它将调用 总和 积累 比率

    如果第二行和/或下一行中的任何一行的值大于 比率 保存为的列 最大限度 身份证件

    升级版
    如果 more than one row where amount = max(amount)

    订货人 条款。就这样结束了 here

    2 回复  |  直到 6 年前
        1
  •  2
  •   S-Man    6 年前

    我不确定我是否完全理解你的问题 ").

    但我相信你在寻找 window functions SUM(ratio) 借助这样的窗口功能。

    这是你期望的吗?

    demo: db<>fiddle

    SELECT DISTINCT ON (name)
        id, 
        name, 
        amount,
        SUM(ratio) OVER (PARTITION BY name)
    FROM test
    ORDER BY name, amount DESC
    

    当然你可以计算 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
    

    不需要 GROUP BY . 好的,但是您需要一个额外的子查询,在这种情况下,您必须过滤窗口函数的结果( amount = max_amount )

        2
  •  0
  •   Eugen Konkov    6 年前

    回答我的问题:

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

    我们必须考虑如果有多行 amount = max(amount)

     id | name | amount | ratio 
    ----+------+--------+-------
      1 | a    |      8 |    10
      2 | a    |      8 |    10
    

    对于此数据,上面的查询将生成错误:

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