Sie, dass als SQL-Funktion halten können, wenn Sie wollen. SQL-Funktionen können mehrere Zeilen durch Ausführen mehrerer SELECT-Abfragen zurückgeben, aber sie können nur mehrere Spalten aus derselben Abfrage zurückgeben. Um also eine SQL-Funktion zu erhalten, müssen Sie eine einzelne Abfrage verwenden, die alle Spalten zurückgibt. Dies könnte mit einem gemeinsamen Tabellenausdruck erreicht werden:
CREATE FUNCTION public.getpogstats(IN p_symbol character varying, IN p_pogtypeid integer, OUT closehi numeric, OUT closelo numeric, OUT dayhi numeric, OUT daylo numeric, OUT s7dhi numeric, OUT s7dlo numeric, OUT t13hi numeric, OUT t13lo numeric, OUT close numeric, OUT firstdate timestamp without time zone)
RETURNS record
LANGUAGE sql
AS $function$
with data1 as (
SELECT ROUND(MAX(closeprice), 2) as closehi,
ROUND(MIN(closeprice), 2) as closelo,
ROUND(MAX(dayhigh), 2) as dayhi,
ROUND(MIN(daylow), 2) as daylo,
ROUND(MAX(sevendaydp), 2) as s7dhi,
ROUND(MIN(sevendaydp), 2) as s7dlo,
ROUND(MAX(thirteendaydp), 2) as t13hi,
ROUND(MIN(thirteendaydp), 2) as t13lo,
MIN(datadate) as firstdate
FROM pogdata
JOIN symbol ON pogdata.symbolid = symbol.symbolid AND pogdata.pogtypeid = p_pogtypeid
WHERE symbol.symbol = p_symbol
), data2 as (
SELECT ROUND(closeprice, 2) as close
FROM pogdata
JOIN symbol ON pogdata.symbolid = symbol.symbolid
WHERE datadate = (SELECT MAX(datadate)
FROM pogdata
JOIN symbol ON pogdata.symbolid = symbol.symbolid AND pogdata.pogtypeid = p_pogtypeid
WHERE symbol.symbol = p_symbol)
AND symbol.symbol = p_symbol
LIMIT 1 -- just to be sure
)
select d1.closehi, d1.closelo, d1.dayhi, d1.daylo, d1.s7dhi, d1.s7dlo, d1.t13hi, d1.t13lo, d2.close, d1.firstdate
from data1 as d1
cross join data2 as d2;
$function$;
(ich habe den Eindruck, die beiden Abfragen in einem kombiniert werden können, aber im Moment kann ich nicht einen Weg finden zu tun)
Beachten Sie, dass Sie, wenn Sie ein Ergebnis mit mehreren Spalten haben möchten (anstatt einer Spalte mit mehreren Feldern), diese explizit erweitern müssen.
folgende Auswahlmöglichkeiten:
select getpogstats('foo', 1);
wird eine einzelne Zeile mit einer einzigen Spalte enthält mehrere Felder zurückkehren, so etwas wie:
getpogstats
-----------
(1,2,3,4,5,6,7,8,9,"2017-05-09 18:19:20")
, weil die Funktion als "RETURNS record" deklariert wird.
Wenn Sie jedoch das Ergebnis als einzelne Spalten wollen, müssen Sie verwenden:
select (getpogstats('foo', 1)).*;
Dann werden Sie jede Spalte separat erhalten:
closehi | closelo | dayhi | ...
--------+---------+-------+----
1 | 2 | 3 | ...
Typischerweise Funktionen Rückkehr Mehr als eine Spalte ist einfacher zu handhaben, wenn Sie sie als returns table (...)
:
CREATE FUNCTION public.getpogstats(p_symbol character varying, p_pogtypeid integer)
returns table(closehi numeric, closelo numeric, dayhi numeric, daylo numeric, s7dhi numeric, s7dlo numeric, t13hi numeric, t13lo numeric, close numeric, firstdate timestamp without time zone)
LANGUAGE sql
AS $function$
with data1 as (
SELECT ROUND(MAX(closeprice), 2) as closehi,
ROUND(MIN(closeprice), 2) as closelo,
ROUND(MAX(dayhigh), 2) as dayhi,
ROUND(MIN(daylow), 2) as daylo,
ROUND(MAX(sevendaydp), 2) as s7dhi,
ROUND(MIN(sevendaydp), 2) as s7dlo,
ROUND(MAX(thirteendaydp), 2) as t13hi,
ROUND(MIN(thirteendaydp), 2) as t13lo,
MIN(datadate) as firstdate
FROM pogdata
JOIN symbol ON pogdata.symbolid = symbol.symbolid AND pogdata.pogtypeid = p_pogtypeid
WHERE symbol.symbol = p_symbol
), data2 as (
SELECT ROUND(closeprice, 2) as close
FROM pogdata
JOIN symbol ON pogdata.symbolid = symbol.symbolid
WHERE datadate = (SELECT MAX(datadate)
FROM pogdata
JOIN symbol ON pogdata.symbolid = symbol.symbolid AND pogdata.pogtypeid = p_pogtypeid
WHERE symbol.symbol = p_symbol)
AND symbol.symbol = p_symbol
LIMIT 1 -- just to be sure
)
select d1.closehi, d1.closelo, d1.dayhi, d1.daylo, d1.s7dhi, d1.s7dlo, d1.t13hi, d1.t13lo, d2.close, d1.firstdate
from data1 as d1
cross join data2 as d2;
$function$;
deklarieren
Dann können Sie verwenden:
select *
from getpogstats('foo', 1);
und das Ergebnis wird eine Struktur „wie Tisch“ automatisch haben.
'select ... in' kann nur mit PL/pgSQL verwendet werden, nicht SQL (auch - nicht verwandt - der Name der Sprache ist ein Bezeichner sollte nicht in einfache Anführungszeichen gesetzt werden, also' same sql' oder 'Sprache plpgsql') –
Danke für die Rückmeldung. Ich habe die Sprache auf "plpgsql" geändert, aber jetzt ist der Fehler: Syntaxfehler bei oder in der Nähe von "SELECT". LINE 6: WÄHLEN SIE RUNDE (MAX (closeprice), 2), RUNDE (MIN (closeprice), 2), ... – KFayal
Sie müssen auch den Rumpf der Funktion ändern, um den Syntaxregeln von PL/pgSQL zu entsprechen: https : //www.postgresql.org/docs/current/static/plpgsql.html –