如何通过总和限制选择?

时间:2013-04-22 06:27:34

标签: sql postgresql sum limit

我想选择我所有最便宜的玩具,共计10.0美元:

也就是说,我想做一些看起来像这样的事情:

select * from toy where sum(price) < 10.0 order by price;

什么是正确的SQL?

为了更清楚,我将添加一个例子。 假设我的表中有这些项目:

       name       | price
------------------+-------
car               |     1
boat              |     2
telephone         |     8
gold bar          |    50

我的结果是:1辆车和1艘船。

总价3美元。我无法选择电话,因为它的金额为13美元,而且大于10美元。

任何想法?

3 个答案:

答案 0 :(得分:4)

尝试:

SELECT a.name, max(a.price) price 
FROM Toy a
JOIN Toy b
  on a.price > b.price or (a.price=b.price and a.name>=b.name)
GROUP BY a.name
HAVING SUM(b.price) <= 10.0
order by 2

SQLFiddle here

答案 1 :(得分:4)

SQL Fiddle

select name, price, total
from (
    select
        name, price,
        sum(price) over(
            order by price
            rows between unbounded preceding and current row
        ) total
    from toy
) s
where total <= 10
order by price

请注意,虽然between unbounded preceding and current row是默认框架,但默认模式为range。因此,必须至少声明rows unbounded preceding,因为当前行是帧结束默认值。

答案 2 :(得分:2)

这是使用递归CTE的实现。还有其他解决方案,您可以谷歌“运行总计”。

WITH RECURSIVE CTE_RN  AS 
(
    SELECT *, ROW_NUMBER() OVER (ORDER BY Price) RN FROM Toys
)
, CTE_Rec AS
(
    SELECT name, price, rn FROM CTE_RN WHERE RN = 1
    UNION ALL
    SELECt r.name, a.price + r.price as price, r.rn FROM CTE_RN r
    INNER JOIN CTE_Rec a on a.RN + 1 = r.RN
    where a.price+r.price <= 10
 )
SELECT name, price as total_price FROM CTE_Rec

SQLFiddle Demo

PS:它在很大程度上取决于RDBMS,因此在开始时包含该信息非常重要。