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

PostgreSQL create_series() s funkcí SQL jako argumenty

To, o co se pokoušíte, by mohlo fungovat takto:

Upravit s dalšími informacemi

CREATE OR REPLACE FUNCTION f_products_per_month()
  RETURNS SETOF fcholder AS
$BODY$
DECLARE
    r fcholder;
BEGIN

FOR r.y, r.m IN
    SELECT to_char(x, 'YYYY')::int4  -- AS y
          ,to_char(x, 'MM')::int4    -- AS m
    FROM  (SELECT '2008-01-01 0:0'::timestamp
        + (interval '1 month' * generate_series(0,57)) AS x) x
LOOP
    RETURN QUERY
    SELECT *    -- use '*' in this case to stay in sync
    FROM   get_forecast_history(r.m, r.y);

    IF NOT FOUND THEN
       RETURN NEXT r;
    END IF;
END LOOP;

END;
$BODY$
  LANGUAGE plpgsql;

Volejte:

SELECT * FROM f_products_per_month();

Hlavní body:

  • Poslední úprava za účelem zahrnutí jinak prázdného řádku pro měsíce bez produktů.
  • Napsali jste „LEFT JOIN“, ale takhle to nemůže fungovat.
  • Existuje několik způsobů, jak to udělat, ale RETURN QUERY je nejelegantnější.
  • Použijte stejný návratový typ, jaký používá vaše funkce get_forecast_history().
  • Vyhněte se konfliktům názvů s parametry OUT tím, že názvy sloupců upravíte podle tabulky (ve finální verzi již nelze použít).
  • Nepoužívejte DATE '2008-01-01' , použijte časové razítko jako já, stejně se musí převést na to_char(). Méně odlévání, lepší výkon (ne že by na tom v tomto případě moc záleželo).
  • '2008-01-01 0:0'::timestamp a timestamp '2008-01-01 0:0' jsou pouze dvě varianty syntaxe, které dělají totéž.
  • U starších verzí PostgreSQL není jazyk plpgsql ve výchozím nastavení nainstalován. Možná budete muset zadat CREATE LANGUAGE plpgsql; jednou ve vaší databázi. Viz příručku zde .

Pravděpodobně byste mohli své dvě funkce zjednodušit do jednoho dotazu nebo funkce, pokud byste chtěli.




  1. Příkaz INSERT v Oracle

  2. Odstraňování problémů s replikací MySQL:Část první

  3. Výběr jednoho řádku v MySQL

  4. SQL:Převádění řádků do sloupců