sql >> Databáze >  >> RDS >> PostgreSQL

Data v intervalu 5 minut dotazu MySQL/Postgres

Rekurzivní CTE

Vzhledem k tomu, že každý řádek závisí na předchozím, je obtížné jej vyřešit pomocí přístupu založeného na množinách. Použití rekurzivního CTE (což je standardní 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;

Všimněte si aktualizace z mého prvního návrhu:
Agregační funkce nejsou povoleny v rekurzivním CTE. Nahradil jsem výrazem ORDER BY / LIMIT 1 , který by měl být rychlý, když je podporován indexem na ts .

Závorky kolem každé větve UNION dotazu jsou nutné k povolení LIMIT , což by jinak bylo povoleno pouze jednou na konci UNION dotaz.

Funkce PL/pgSQL

Procedurální řešení (příklad s funkcí plpgsql) procházející setříděnou tabulkou by pravděpodobně bylo mnohem rychlejší, protože si vystačí s jedním prohledáním tabulky:

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;

Volejte:

SELECT * FROM  f_rowgrid('5 min')

SQL Fiddle předvedení obojího.

Zde je poněkud složitější příklad pro tento typ funkce plpgsql:

Mohl by být snadno generován pomocí dynamického SQL a EXECUTE pracovat pro libovolné tabulky.




  1. Vytvořte funkci MySQL v Laravel 5.5

  2. CI – ukaž mi, co se pokazilo

  3. Poskytování oprávnění systému postgres ke kopírování (Windows 8)

  4. Rozdíl mezi DataSource a ConnectionPoolDataSource