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;
Ciò presuppone un id
univoco crescente come hai nel tuo esempio.
Nel moderno Postgres - o in generale con SQL standard moderno (ma non in SQLite):
CTE semplice
WITH cte AS (
SELECT *, sum(verbosity) OVER (ORDER BY id) AS total
FROM messages
)
SELECT *
FROM cte
WHERE total <= 70
ORDER BY id;
CTE ricorsivo
Dovrebbe essere più veloce per i tavoli grandi in cui recuperi solo un piccolo set.
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;
Tutte le funzionalità standard, ad eccezione di LIMIT
.
A rigor di termini, non esiste una cosa come "indipendente dal database". Esistono vari standard SQL, ma nessun RDBMS è completamente conforme. LIMIT
funziona per PostgreSQL e SQLite (e alcuni altri). Usa TOP 1
per SQL Server, rownum
per Oracle. Ecco un elenco completo su Wikipedia.
Lo standard SQL:2008 sarebbe:
...
FETCH FIRST 1 ROWS ONLY
... che supporta PostgreSQL, ma quasi nessun altro RDBMS.
La pura alternativa che funziona con più sistemi sarebbe quella di avvolgerlo in una sottoquery e
SELECT max(total) FROM <subquery>
Ma è lento e ingombrante.
SQL Fiddle.