hallo,
ich möchte gerne eine pgsql funktion schreiben in der ich folgendes mache
FOR RECORD_A IN QUERY_A LOOP
FOR RECORD_B IN QUERY_B LOOP
RETURN NEXT RECORD_A, RECORD_B;
END LOOP;
END LOOP;
Return ist setof RECORD
das Proble ist allerdings das er das , beim return next nicht mag (PG 8.3)
wie kann ich 2 records kombinieren damit ich es als eine zeile ausgeben kann ?
Als zwei RECORDs sowieso nicht. Außerdem musst du die Struktur des Records angeben.
Ev. kannst du alles in einem RECORD oder in einem eigenen Datentyp zusammenfassen.
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören
Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler
PostgreSQL Service & Support
>Ev. kannst du alles in einem RECORD ... zusammenfassen.
Genau das
Aber wie ?
Das proble ist das ich eine sehr breite und lange tabelle habe.
davon gibts eine pro monat eines jahres.
ich selectiere alle spalten von einer tabelle, summiere das aufkommen von werten und limitiere das ergebnis auf z.B. 100.
nun möchte ich diese (ich sage mal top 100) aus der tabelle des vormonats bekommen. bzw will von diesen einträgen wieder die anzahl wissen
mit UNION oder sum(a.x), sum(b.x) where ... flippt mein speicher aus. selbst wenn ich eine solche view kreire und die über cursor auslesen möchte macht der speicher nicht mit. eplain zeigt mir auch unglaubliche werte an für die performance weil es halt soviele daten sind.
von daher mache ich den select den ich will auf monnat 1, in der for schleife dann die von werte rausholen bei monat 2 ...
also
mit dem text aneinanderreihen geht es (klar) und dann opacke ich excel aus und importiere das ergebnis. aber direkt als record ergebnis klappt das nicht weil ich die e_query und e_subquery nciht verheiraten kannCREATE OR REPLACE FUNCTION special(
) RETURNS SETOF text AS
$$
DECLARE
e_sum text;
e_query RECORD;
e_subquery RECORD;
e_subsubquery RECORD;
BEGIN
FOR e_query IN (select cap_brand_name, cap_model_name, cap_device_os_vendor, cap_device_os_name, cap_device_os_osversion, sum(sccount) as okt from servercalls_10_2009 NATURAL JOIN uasmeta WHERE cap_device_type = 'mobile' group by cap_brand_name, cap_model_name, cap_device_os_vendor, cap_device_os_name, cap_device_os_osversion ORDER BY okt DESC limit 75)
LOOP
FOR e_subquery IN (select sum(sccount) as sept from servercalls_09_2009 NATURAL JOIN uasmeta WHERE cap_device_type = 'mobile' AND cap_brand_name = e_query.cap_brand_name AND cap_model_name = e_query.cap_model_name AND cap_device_os_vendor = e_query.cap_device_os_vendor AND cap_device_os_name = e_query.cap_device_os_name AND cap_device_os_osversion = e_query.cap_device_os_osversion)
LOOP
FOR e_subsubquery IN (select sum(sccount) as aug from servercalls_08_2009 NATURAL JOIN uasmeta WHERE cap_device_type = 'mobile' AND cap_brand_name = e_query.cap_brand_name AND cap_model_name = e_query.cap_model_name AND cap_device_os_vendor = e_query.cap_device_os_vendor AND cap_device_os_name = e_query.cap_device_os_name AND cap_device_os_osversion = e_query.cap_device_os_osversion)
LOOP
e_sum = e_query.cap_brand_name || '|' || e_query.cap_model_name || '|' || e_query.cap_device_os_vendor || '|' || e_query.cap_device_os_name || '|' || e_query.cap_device_os_osversion || '|' || e_query.okt || '|' || e_subquery.sept || '|' || e_subsubquery.aug;
RETURN NEXT e_sum;
END LOOP;
END LOOP;
END LOOP;
END;
$$
LANGUAGE plpgsql;
select * FROM special() as (liste text)![]()
Das ist keine Fehlermeldung.
Mir scheint, Du machst ein Kreuzprodukt. Da sind drei Schleifen. Die äußere bringt ein Resultat. Für jedes davon machst Du wieder ein Select, mittlere Schleife. Angenommen, die äußere liefert 5 Zeilen und die mittlere 4, dann sind das schon 20. Und dann eine dritte schleife, die 'nur' 3 Zeilen liefert, aber das rufst Du nun 20 mal auf. Rechne das mal auf größere Zahlen hoch.selbst wenn ich eine solche view kreire und die über cursor auslesen möchte macht der speicher nicht mit. eplain zeigt mir auch unglaubliche werte an für die performance weil es halt soviele daten sind.
von daher mache ich den select den ich will auf monnat 1, in der for schleife dann die von werte rausholen bei monat 2 ...
also
mit dem text aneinanderreihen geht es (klar) und dann opacke ich excel aus und importiere das ergebnis. aber direkt als record ergebnis klappt das nicht weil ich die e_query und e_subquery nciht verheiraten kann![]()
Deine Bemerkung, der Speicher reiche nicht, und dann, daß Du das ins Excel kippst, passen nicht zusammen. Excel implodiert bei etwas über 65.000 Zeilen, das ist etwas, wo PG noch nicht mal tief Luft holen muß.
Vorschlag:
Da ich zu faul bin, Deine Tabellen zu erraten. erstellst Du beispielhafte Tabellen, füllst diese mit ein paar Zeilen, und bringst die CREATE und INSERT - Befehle hier copy&paste - fähig.
Dann zeigst Du uns, was raus kommen soll.
Wir sehen dann weiter.
Andreas
--
https://www.xing.com/profile/Andreas_Kretschmer7ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
Alternativ biete ich an, das komplette System mit zu überarbeiten:
Monatsweise Daten, breite Tabellen, RECORD-Datentypen, massenweise Joins, Views, Cursor ... das hört sich nach Optimierungspotential an.
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören
Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler
PostgreSQL Service & Support
Links: Tobias Bauer - IT- und Funkdienstleistungen - Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen - Funkforum
Lesezeichen