I have a table that stores basic information about files:
CREATE TABLE filez (
id INTEGER NOT NULL,
name TEXT NOT NULL,
size BIGINT NOT NULL
);
CREATE UNIQUE INDEX filez__id__idx ON filez USING (id);
I need to select a set of files with combined size that does not exceed some THRESHOLD. The following is a trivialized query which achieves that (it could use the NON MATERIALIZED CTE syntax, but that is not important in this case):
SELECT id, name
FROM (
SELECT id, name,
SUM(size) OVER w AS total_size -- accumulating size of files
FROM filez
WINDOW w AS (ORDER BY id ASC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
ORDER BY id ASC
) AS t
WHERE total_size <= THRESHOLD
I have a personal 😄 problem with this query: it goes over ALL records regardless whether the threshold was reached. I’d like the query to go over just the sufficient number of records (sorted by an indexed "id" field) and stop executing as soon as the threshold condition becomes false.
EDIT.
Maybe the problem of stopping a query could be generalized. If there was a function, let’s call it stop_query(BOOL):BOOL
which could prematurely end query execution based on arbitrary condition, as in the following example:
SELECT f1, f2
FROM tab1
WHERE stop_query(<some condition>)
alternatively
SELECT f1, f2
FROM tab1
WHERE CASE WHEN <some condition> THEN stop_query() ELSE TRUE END
2
Answers
You can put the query in a cte and add your ordering criteria in your query
sum over
.Then just select the data from this cte.
You could use a cursor-based function: demo
fiddle