SELECT m.id, sum(m1.verbosity) AS total
FROM messages m
JOIN messages m1 ON m1.id <= m.id
WHERE m.verbosity < 70 -- optional, to avoid pointless evaluation
GROUP BY m.id
HAVING SUM(m1.verbosity) < 70
ORDER BY total DESC
LIMIT 1;
Dies setzt eine eindeutige, aufsteigende id
voraus wie in deinem Beispiel.
In modernem Postgres - oder allgemein mit modernem Standard-SQL (aber nicht in SQLite):
Einfacher CTE
WITH cte AS (
SELECT *, sum(verbosity) OVER (ORDER BY id) AS total
FROM messages
)
SELECT *
FROM cte
WHERE total <= 70
ORDER BY id;
Rekursiver CTE
Sollte für große Tabellen schneller sein, wo Sie nur einen kleinen Satz abrufen.
WITH RECURSIVE cte AS (
( -- parentheses required
SELECT id, verbosity, verbosity AS total
FROM messages
ORDER BY id
LIMIT 1
)
UNION ALL
SELECT c1.id, c1.verbosity, c.total + c1.verbosity
FROM cte c
JOIN LATERAL (
SELECT *
FROM messages
WHERE id > c.id
ORDER BY id
LIMIT 1
) c1 ON c1.verbosity <= 70 - c.total
WHERE c.total <= 70
)
SELECT *
FROM cte
ORDER BY id;
Alle Standardfunktionen, außer LIMIT
.
„Datenbankunabhängig“ gibt es streng genommen nicht. Es gibt verschiedene SQL-Standards, aber kein RDBMS erfüllt diese vollständig. LIMIT
funktioniert für PostgreSQL und SQLite (und einige andere). Verwenden Sie TOP 1
für SQL Server rownum
für Oracle. Hier ist eine umfassende Liste auf Wikipedia.
Der SQL:2008-Standard wäre:
...
FETCH FIRST 1 ROWS ONLY
... die PostgreSQL unterstützt - aber kaum andere RDBMS.
Die reine Alternative, die mit mehr Systemen funktioniert, wäre, sie in eine Unterabfrage und
einzuschließenSELECT max(total) FROM <subquery>
Aber das ist langsam und unhandlich.
SQL-Geige.