sql >> Database teknologi >  >> RDS >> PostgreSQL

SQL vælg elementer, hvor summen af ​​feltet er mindre end N

SELECT m.id, sum(m1.verbosity) AS totalFROM messages mJOIN messages m1 ON m1.id <=m.idWHERE m.verbosity <70 -- valgfrit, for at undgå meningsløs evaluering GRUPPE EFTER m.idHAVING SUM (m1.verbosity) <70ORDER BY total DESCLIMIT 1; 

Dette forudsætter et unikt, stigende id som du har i dit eksempel.

I moderne Postgres - eller generelt med moderne standard SQL (men ikke i SQLite):

Simpel CTE

MED cte AS ( SELECT *, sum(ombosity) OVER (ORDER BY id) AS total FROM messages )SELECT *FROM cteWHERE total <=70ORDER BY id; 

Rekursiv CTE

Bør være hurtigere for store borde, hvor du kun henter et lille sæt.

MED REKURSIV cte AS ( ( -- parentes påkrævet SELECT id, verbosity, verbosity AS total FROM messages ORDER BY id LIMIT 1 ) UNION ALL SELECT c1.id, c1.verbosity, c.total + c1.verbosity FRA cte c JOIN LATERAL (VÆLG * FRA beskeder HVOR id> c.id ORDER BY id LIMIT 1 ) c1 ON c1.verbosity <=70 - c.total WHERE c.total <=70 )VÆLG *FRA cteORDER BY id;

Alle standardfunktioner, undtagen LIMIT .

Strengt taget er der ikke noget, der hedder "database-uafhængig". Der findes forskellige SQL-standarder, men ingen RDBMS overholder fuldstændigt. LIMIT virker til PostgreSQL og SQLite (og nogle andre). Brug TOP 1 for SQL Server, rownum for Oracle. Her er en omfattende liste på Wikipedia.

SQL:2008-standarden ville være:

...HENT KUN FØRSTE 1 RÆKKER 

... som PostgreSQL understøtter - men næppe nogen anden RDBMS.

Det rene alternativ, der fungerer med flere systemer, ville være at pakke det ind i en underforespørgsel og

VÆLG max(total) FRA  

Men det er langsomt og uhåndterligt.

SQL Fiddle.



  1. Sådan afbrydes udførelsen af ​​en erklæring i PostgreSQL

  2. Hvordan man ikke viser dubletter i SQL

  3. Script hele databasen SQL-Server

  4. Spar tid ved at køre Microsoft Access-rapporter ved hjælp af filtre i layoutvisning