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;
Cela suppose un id
unique et croissant comme vous l'avez dans votre exemple.
Dans Postgres moderne - ou généralement avec SQL standard moderne (mais pas en SQLite) :
CTE simple
WITH cte AS (
SELECT *, sum(verbosity) OVER (ORDER BY id) AS total
FROM messages
)
SELECT *
FROM cte
WHERE total <= 70
ORDER BY id;
CTE récursif
Devrait être plus rapide pour les grandes tables où vous ne récupérez qu'un petit ensemble.
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;
Toutes les fonctionnalités standard, à l'exception de LIMIT
.
Strictement parlant, il n'existe pas de "base de données indépendante". Il existe différentes normes SQL, mais aucun SGBDR ne s'y conforme complètement. LIMIT
fonctionne pour PostgreSQL et SQLite (et quelques autres). Utilisez TOP 1
pour SQL Server, rownum
pour Oracle. Voici une liste complète sur Wikipédia.
La norme SQL:2008 serait :
...
FETCH FIRST 1 ROWS ONLY
... que PostgreSQL prend en charge - mais pratiquement aucun autre SGBDR.
L'alternative pure qui fonctionne avec plus de systèmes serait de l'envelopper dans une sous-requête et
SELECT max(total) FROM <subquery>
Mais c'est lent et peu maniable.
SQL Fiddle.