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