问题是:
如何获取由汇总函数选择的行?
问题was answered并部分解决了我的问题。但由于以下原因,我仍然无法用GROUP BY
替换DISTINCT ON
:
我都需要:
id
(可以用DISTINCT ON
解决)ratio
列求和(可以用GROUP BY
进行解析)用户消耗了amount
的某些资源。第10天的一天用户消耗8
的一部分,而另一天的10h用户消耗3
,而4h的用户不消耗资源。该任务是最大程度地为消耗的资源开票,而不在不消耗资源时开票
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
为什么不允许将聚合函数与DISTINCT 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
这还将解决ORDER BY
的问题。不需要workaround with subquery
是否有技术上的原因不允许上一个示例中的查询按所述方式工作?
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
如果第二行和/或下一个非区别行中的任何一个对于ratio
列具有更大的值,则将其另存为最大值,并为id
保存的值将被更新
UPD
如果more than one row where amount = max(amount)
Postgres可以从任一行返回值。因为这是针对不在DISTINCT ON下的任何字段完成的
为确保返回哪个查询,查询可以通过ORDER BY
子句进行限定。像这样here
答案 0 :(得分:1)
我不确定我是否能完全理解您的问题(我不理解“ 10h用户”部分)。
但是我相信您正在搜索window functions。我从另一个问题中拉开了小提琴,并借助这种窗口函数添加了SUM(ratio)
。
这是您期望的吗?
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
)的结果
答案 1 :(得分:0)
回答我的问题:
是否有技术原因不允许上一个示例中的查询按所述方式工作?
如果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