PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

SQL-Select-Elemente, bei denen die Feldsumme kleiner als N ist

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ßen
SELECT max(total) FROM <subquery>

Aber das ist langsam und unhandlich.

SQL-Geige.