Ich habe diese Funktion in PostgreSQL, aber ich weiß nicht, wie ich das Ergebnis der Abfrage zurückgeben soll:
CREATE OR REPLACE FUNCTION wordFrequency(maxTokens INTEGER)
RETURNS SETOF RECORD AS
$$
BEGIN
SELECT text, count(*), 100 / maxTokens * count(*)
FROM (
SELECT text
FROM token
WHERE chartype = 'ALPHABETIC'
LIMIT maxTokens
) as tokens
GROUP BY text
ORDER BY count DESC
END
$$
LANGUAGE plpgsql;
Ich weiß jedoch nicht, wie ich das Ergebnis der Abfrage innerhalb der PostgreSQL-Funktion zurückgeben soll.
Ich fand, dass der Rückgabetyp sein sollte SETOF RECORD
, richtig? Der Rückgabebefehl ist jedoch nicht richtig.
Was ist der richtige Weg, um dies zu tun?
sql
postgresql
return
plpgsql
return-type
Renato Dinhani
quelle
quelle
LANGUAGE SQL
.Antworten:
Verwendung
RETURN QUERY
:Anruf:
Erläuterung:
Es ist viel praktischer, den Rückgabetyp explizit zu definieren, als ihn einfach als Datensatz zu deklarieren. Auf diese Weise müssen Sie nicht bei jedem Funktionsaufruf eine Spaltendefinitionsliste bereitstellen.
RETURNS TABLE
ist eine Möglichkeit, das zu tun. Da sind andere. Datentypen vonOUT
Parametern müssen genau mit dem übereinstimmen, was von der Abfrage zurückgegeben wird.Wählen Sie die Namen der
OUT
Parameter sorgfältig aus. Sie sind im Funktionskörper fast überall sichtbar. Gleichnamige Spalten mit Tabellenqualifizierung, um Konflikte oder unerwartete Ergebnisse zu vermeiden. Ich habe das für alle Spalten in meinem Beispiel gemacht.Beachten Sie jedoch den möglichen Namenskonflikt zwischen dem
OUT
Parametercnt
und dem gleichnamigen Spaltenalias. In diesem speziellen Fall (RETURN QUERY SELECT ...
) verwendet Postgres den Spaltenalias über denOUT
Parameter. Dies kann jedoch in anderen Kontexten nicht eindeutig sein. Es gibt verschiedene Möglichkeiten, um Verwirrung zu vermeiden:ORDER BY 2 DESC
. Beispiel:ORDER BY count(*)
.plpgsql.variable_conflict
oder verwenden Sie den Sonderbefehl#variable_conflict error | use_variable | use_column
in der Funktion. Sehen:Verwenden Sie nicht "Text" oder "Anzahl" als Spaltennamen. Beide sind in Postgres legal zu verwenden, aber "count" ist ein reserviertes Wort in Standard-SQL und ein grundlegender Funktionsname und "text" ist ein grundlegender Datentyp. Kann zu verwirrenden Fehlern führen. Ich benutze
txt
undcnt
in meinen Beispielen.Ein fehlender
;
und korrigierter Syntaxfehler im Header wurde hinzugefügt .(_max_tokens int)
, Nicht(int maxTokens)
- geben Sie nach dem Namen .Bei der Arbeit mit der Ganzzahldivision ist es besser, zuerst zu multiplizieren und später zu dividieren, um den Rundungsfehler zu minimieren. Noch besser: Arbeiten Sie mit
numeric
(oder einem Gleitkomma-Typ). Siehe unten.Alternative
Ich denke, Ihre Abfrage sollte tatsächlich so aussehen (Berechnung eines relativen Anteils pro Token ):
Der Ausdruck
sum(t.cnt) OVER ()
ist eine Fensterfunktion . Sie könnten einen CTE anstelle der Unterabfrage verwenden - hübsch, aber eine Unterabfrage ist in einfachen Fällen wie diesem normalerweise billiger.Eine abschließende explizite
RETURN
Anweisung ist nicht erforderlich (aber zulässig), wenn mitOUT
Parametern gearbeitet wird oderRETURNS TABLE
( wobei Parameter implizit verwendetOUT
werden).round()
mit zwei Parametern funktioniert nur fürnumeric
Typen.count()
in der Unterabfrage ergibt sich einbigint
Ergebnis und einsum()
Overbigint
erzeugt einnumeric
Ergebnis, daher behandeln wirnumeric
automatisch eine Zahl und alles passt einfach zusammen.quelle
RETURN;
vorher eine brauchstEND;
, zumindest habe ich das getan - aber ich mache eine UNION, also bin ich mir nicht sicher, ob das den Unterschied macht.RETURN
. Ein nicht verwandter Fehler wurde behoben und einige Verbesserungen hinzugefügt, während Sie dabei waren.Hallo, bitte überprüfen Sie den folgenden Link
https://www.postgresql.org/docs/current/xfunc-sql.html
EX:
quelle