sql >> Databasteknik >  >> RDS >> PostgreSQL

MySQL/Postgres frågar 5 minuters intervalldata

Rekursiv CTE

Eftersom varje rad beror på den tidigare, är det svårt att lösa med ett set-baserat tillvägagångssätt. Tillgripa en rekursiv CTE (som är standard SQL):

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;

Notera uppdateringen från mitt första utkast:
Aggregerade funktioner är inte tillåtna i en rekursiv CTE. Jag ersatte med ORDER BY / LIMIT 1 , vilket bör vara snabbt när det stöds av ett indexts .

Parentesen runt varje ben i UNION fråga är nödvändiga för att tillåta LIMIT , som annars bara skulle vara tillåtet en gång i slutet av en UNION fråga.

PL/pgSQL-funktion

En procedurlösning (exempel med en plpgsql-funktion) som itererar genom den sorterade tabellen skulle förmodligen vara mycket snabbare, eftersom den kan nöja sig med en enda tabellskanning:

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;

Ring:

SELECT * FROM  f_rowgrid('5 min')

SQL Fiddle demonstrerar båda.

Här är ett något mer komplext exempel för denna typ av plpgsql-funktion:

Kan enkelt göras generisk med dynamisk SQL och EXECUTE att arbeta för godtyckliga tabeller.




  1. CI - visa mig vad som gick fel

  2. Ange standardschema för JDBC-pool i weblogic/oracle

  3. Hur man skapar och underhåller MySQL-databaser i cPanel

  4. PHP MySQL-anslutningsbeständighet