sql >> Database >  >> RDS >> PostgreSQL

MySQL/Postgres-query 5 minuten intervalgegevens

Recursieve CTE

Omdat elke rij afhangt van de vorige, is het moeilijk op te lossen met een set-gebaseerde benadering. Toevlucht nemen tot een recursieve CTE (wat standaard SQL is):

WITH RECURSIVE cte AS (
   (SELECT ts FROM tbl
    ORDER  BY ts
    LIMIT  1)

   UNION ALL
   (SELECT t.ts
    FROM   cte c
    JOIN   tbl t ON t.ts >= c.ts + interval '5 min'
    ORDER  BY t.ts
    LIMIT  1)
   )
SELECT * FROM cte ORDER BY ts;

Let op de update van mijn eerste concept:
Geaggregeerde functies zijn niet toegestaan ​​in een recursieve CTE. Ik heb vervangen door ORDER BY / LIMIT 1 , wat snel zou moeten zijn als het wordt ondersteund door een index op ts .

De haakjes rond elk been van de UNION zoekopdracht zijn nodig om LIMIT . toe te staan , die anders slechts één keer zou zijn toegestaan ​​aan het einde van een UNION vraag.

PL/pgSQL-functie

Een procedurele oplossing (bijvoorbeeld met een plpgsql-functie) die de gesorteerde tabel doorloopt, zou waarschijnlijk een stuk sneller zijn, aangezien het kan volstaan ​​met een enkele tabelscan:

CREATE OR REPLACE FUNCTION f_rowgrid(i interval)
  RETURNS SETOF timestamp AS
$func$
DECLARE
   _this  timestamp;
   _last  timestamp := '-infinity';     -- init so that 1 row passes
BEGIN

FOR _this IN
    SELECT ts FROM tbl ORDER BY 1
LOOP
    IF _this >= _last + i THEN
       RETURN NEXT _this;
       _last := _this;
    END IF;
END LOOP;

END
$func$ LANGUAGE plpgsql;

Bel:

SELECT * FROM  f_rowgrid('5 min')

SQL Fiddle beide demonstreren.

Hier is een wat complexer voorbeeld voor dit type plpgsql-functie:

Kan gemakkelijk generiek worden gemaakt met dynamische SQL en EXECUTE om voor willekeurige tabellen te werken.




  1. Hoe kan ik de waarde optellen in de kamerdatabase Android?

  2. Waarom crashte mijn MySQL-database? Krijg inzichten met het nieuwe MySQL Freeze Frame

  3. Kan DLL 'SqlServerSpatial.dll' niet laden

  4. Hoe wijzig ik in SQL*Plus de prompt om de verbonden gebruiker en database weer te geven?