查询最小行数以匹配给定值阈值

Query smallest number of rows to match a given value threshold

我想创建一个类似于收银机的查询。想象一个收银机,里面装满了不同大小的硬币。我想以尽可能少的硬币数量检索硬币的总价值。

鉴于此 table:

id value
1 100
2 100
3 500
4 500
5 1000

我将如何查询以下行的列表:

例如,如果我的阈值是 1050,这将是预期的结果:

id value
1 100
5 1000

我正在使用 postgres 和 elixir/ecto。如果它可以在单个查询中完成很好,如果它需要一系列多个查询没问题。

我自己试了一下,使用了之前问题的答案:

  • Using ABS() to order by the closest value to the threshold

根据上面@TheImpaler 的评论,这会优先考虑最小行数而不是最小超额行数。这不是我想要的 100%,所以如果有人可以的话,欢迎改进,但如果不是,我认为这已经足够好了:

-- outer query selects all rows underneath the threshold
-- inner subquery adds a running total column
-- window function orders by the difference between value and threshold
SELECT
    *
FROM (
    SELECT
        i.*,
        SUM(i.value) OVER (
            ORDER BY
                ABS(i.value - $THRESHOLD),
                i.id
        ) AS total
    FROM
        inputs i
    ) t
WHERE
    t.total - t.value < $THRESHOLD;