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;
Ini mengasumsikan id
yang unik dan naik seperti yang Anda miliki dalam contoh Anda.
Di Postgres modern - atau umumnya dengan SQL standar modern (tapi tidak dalam SQLite):
CTE Sederhana
WITH cte AS (
SELECT *, sum(verbosity) OVER (ORDER BY id) AS total
FROM messages
)
SELECT *
FROM cte
WHERE total <= 70
ORDER BY id;
CTE Rekursif
Seharusnya lebih cepat untuk tabel besar di mana Anda hanya mengambil satu set kecil.
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;
Semua fitur standar, kecuali LIMIT
.
Sebenarnya, tidak ada yang namanya "database-independen". Ada berbagai standar SQL, tetapi tidak ada RDBMS yang sepenuhnya mematuhi. LIMIT
bekerja untuk PostgreSQL dan SQLite (dan beberapa lainnya). Gunakan TOP 1
untuk SQL Server, rownum
untuk Oracle. Berikut daftar lengkapnya di Wikipedia.
Standar SQL:2008 adalah:
...
FETCH FIRST 1 ROWS ONLY
... yang didukung PostgreSQL - tetapi hampir tidak ada RDBMS lainnya.
Alternatif murni yang bekerja dengan lebih banyak sistem adalah dengan membungkusnya dalam subquery dan
SELECT max(total) FROM <subquery>
Tapi itu lambat dan berat.
SQL Fiddle.