我想编写一个查询,从有序表中获取行,同时聚合一列的值,直到所述聚合值满足所需的阈值。
另一个标准是,通过阈值的违规行应包含在查询结果中。
我寻找了 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 函数来实现这一点,尽管我不知道从哪里开始进行这种聚合查询。
如果有人有任何想法或专业知识,我将不胜感激。
在窗口函数的
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
);
如果您想要最后一行(越过阈值的一行),您有两个相对简单的选择。我的偏好是:
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;