我想编写一个从有序表中获取行的查询,同时聚合一列的值,直到所述聚合值达到所需的阈值。
另一个标准是通过阈值的违规行应该包含在查询结果中。
我已经在PostgreSQL中寻找其他解决方案,导致我创建以下查询:
SELECT * FROM (
SELECT *, SUM(amount) OVER (ORDER BY amount DESC) AS running_amount
FROM public.orders WHERE price = 0.09) AS t
WHERE t.running_amount <= 15;
此查询的问题是,它表示PostgreSQL窗口查询,如果给定行的列值不唯一,则会跳过所有行的列值聚合。
不幸的是,窗口查询不支持考虑不同值列的考虑。
我听到的一些替代方案仍然是通过创建PostgreSQL函数,虽然我不知道从哪里开始这种聚合查询。
如果有人有任何想法或技术诀窍,我将不胜感激。
答案 0 :(得分:1)
将唯一列(主键)添加到窗口函数的ORDER BY
子句中,例如:
SELECT * FROM (
SELECT *, SUM(amount) OVER (ORDER BY amount DESC, id) AS running_amount
FROM public.orders WHERE price = 0.09
) AS t
WHERE t.running_amount <= 15;
如果缺少唯一列,您可以使用系统列ctid.
您可以使用UNION ALL
来获取超过阈值的违规行,例如:
WITH cte AS (
SELECT *, SUM(amount) OVER (ORDER BY amount DESC, id) AS running_amount
FROM public.orders
WHERE price = 0.09
)
SELECT *
FROM cte
WHERE running_amount <= 15
UNION ALL (
SELECT *
FROM cte
WHERE running_amount > 15
LIMIT 1
);
答案 1 :(得分:1)
如果你想要最后一行(超过阈值的那一行),你有两个相对简单的选择。我的偏好是:
SELECT o.*
FROM (SELECT o.*,
SUM(amount) OVER (ORDER BY amount DESC) AS running_amount
FROM public.orders
WHERE price = 0.09
) o
WHERE o.running_amount - o.amount <= 15;
替代方案是一个窗口条款:
SELECT o.*
FROM (SELECT o.*,
SUM(amount) OVER (ORDER BY amount DESC
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
) AS running_amount
FROM public.orders
WHERE price = 0.09
) o
WHERE o.running_amount <= 15;