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;
这假设一个独特的、上升的,id
就像你在你的例子中一样。
在现代 Postgres 中 - 或者通常使用现代标准 SQL(但不在SQLite 中):
简单 CTE
WITH cte AS (
SELECT *, sum(verbosity) OVER (ORDER BY id) AS total
FROM messages
)
SELECT *
FROM cte
WHERE total < 70
ORDER BY id;
递归 CTE
对于只检索小集合的大表应该更快。
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;
所有标准 SQL,除了LIMIT
.
严格来说,不存在“独立于数据库”之类的东西。有各种 SQL 标准,但没有一个 RDBMS 完全符合。LIMIT
适用于 PostgreSQL 和 SQLite(以及其他一些)。用于TOP 1
SQL Server,rownum
用于 Oracle。这是Wikipedia 上的完整列表。
SQL:2008 标准将是:
...
FETCH FIRST 1 ROWS ONLY
... PostgreSQL 支持 - 但几乎没有任何其他 RDBMS。
与更多系统一起使用的纯粹替代方法是将其包装在子查询中并
SELECT max(total) FROM <subquery>
但这是缓慢且笨拙的。
db<>fiddle here
旧sqlfiddle