5

我想选择我库存中所有最便宜的玩具,总计 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。

有任何想法吗?

4

3 回答 3

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在这里

于 2013-04-22T06:54:40.050 回答
4

SQL小提琴

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声明当前行是帧结束默认值。

于 2013-04-22T10:57:05.820 回答
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 演示

PS:这在很大程度上取决于 RDBMS,这就是为什么在开始时包含该信息很重要的原因。

于 2013-04-22T07:00:59.890 回答