Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 18

Thema: Aggregat- / Trendfunktion

  1. #1
    Hanno ist offline Neuer Benutzer
    Registriert seit
    21.01.2010
    Beiträge
    26

    Standard Aggregat- / Trendfunktion

    Hallo,

    Ich habe einmal ein kleines problem und benötige etwas Hilfe. Ich würde gern ein Art Trend für DB Einträge ausgeben lassen. ich habe folgende Tabellenstruktur:

    indikator|jahr|datenwert|raumeinheit
    106|1991|8238|1201
    106|1992|8215|1201
    106|1993|8218|1201
    106|1994|8330|1201
    106|1995|8340|1201
    106|1996|8123|1201

    Der Trend soll sich jetzt folgendermassen berechnen:
    Summe (Steigungen) / Summe Gewichtungen

    -> Steigungen = (Datenwert im Jahr 1996 / Datenwert im Jahr 1995) * Gewichtung
    Gewichtung soll beim 1. Wert 1 betragen. Bei den folgenden Intervallen wird die Gewichtung dann jeweils halbiert.

    Formel: Trend = ((Wert1996/Wert1995)*1 + (Wert1995/Wert1994)*0.5 + (Wert1994/Wert1993)*0.25 +...) / Anzahl Intervalle

    Trend = ((8123/8340)*1+(8340/8330)*0.5+(8330/8218)*0.25+...)/5

    Ich bin mir jetzt nicht ganz sicher ob das so abzufragen geht. Eventuell muss man da auch eine eigene Aggregatfunktion schreiben, dann müsste ich nicht jedesmal den ganzen String eingeben? Kann mir da vielleicht jemand behilflich sein? Es gibt hier ja bestimmt ein paar Fachleute, für die das Ganze nicht soviel Arbeit bedeuten würde wie für mich. ich hoffe ich hab jetzt verständlich genug erklärt was ich denn haben möchte. Ansonsten fragt doch einfach nochmal nach, bitte.

    Für Eure Hilfe bedanke ich mich schon einmal ganz herzlich im Voraus.

    Gruss
    Hanno

    Ergänzung: In der Tabelle stehen natürlich noch mehr Daten drin. Diese können dann auch eine andere Raumeinheit haben. primärschlüssel wäre hier indikator;jahr;raumeinheit
    z.B.
    106|1991|8001|1202
    106|1992|8002|1202
    106|1993|8003|1203
    106|1994|8004|1203
    106|1995|8005|1204
    106|1996|8006|1204

    Der Trend soll dann immer nur für eine Raumeinheit über alle vorliegenden Jahre berechnet werden. Eine Funktion müsste dann also die Raumeinheit als Argument übergeben bekommen.

    Nochmals Vielen Dank für Eure Hilfe.
    Hanno
    Geändert von Hanno (31.05.2010 um 12:05 Uhr)

  2. #2
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von Hanno Beitrag anzeigen
    Hallo,

    Ich habe einmal ein kleines problem und benötige etwas Hilfe. Ich würde gern ein Art Trend für DB Einträge ausgeben lassen. ich habe folgende Tabellenstruktur:

    indikator|jahr|datenwert|raumeinheit
    106|1991|8238|1201
    106|1992|8215|1201
    106|1993|8218|1201
    106|1994|8330|1201
    106|1995|8340|1201
    106|1996|8123|1201

    Der Trend soll sich jetzt folgendermassen berechnen:
    Summe (Steigungen) / Summe Gewichtungen

    -> Steigungen = (Datenwert im Jahr 1996 / Datenwert im Jahr 1995) * Gewichtung
    Gewichtung soll beim 1. Wert 1 betragen. Bei den folgenden Intervallen wird die Gewichtung dann jeweils halbiert.

    Formel: Trend = ((Wert1996/Wert1995)*1 + (Wert1995/Wert1994)*0.5 + (Wert1994/Wert1993)*0.25 +...) / Anzahl Intervalle

    Trend = ((8123/8340)*1+(8340/8330)*0.5+(8330/8218)*0.25+...)/5
    Als kleiner Ansatz vielleicht window-functions? Damit könntest Du den jeweiligen Vorgänger und den Multiplikationsfaktor berechnen (ich hab nur grad einen Knoten im Hirn, daher ist der Faktor nicht wirklich der, den Du willst, sondern 1/N)

    Code:
    test=*# select jahr, datenwert, lead(datenwert) over(order by jahr desc), (1::float / row_number() over(order by jahr desc))::numeric(4,3) as faktor from hanno order by jahr desc;
     jahr | datenwert | lead | faktor
    ------+-----------+------+--------
     1996 |      8123 | 8340 |  1.000
     1995 |      8340 | 8338 |  0.500
     1994 |      8338 | 8218 |  0.333
     1993 |      8218 | 8215 |  0.250
     1992 |      8215 | 8238 |  0.200
     1991 |      8238 |      |  0.167
    (6 Zeilen)
    In dieser Tabelle hast Du nun alle Werte und könntest daraus dann gemäß Deiner Formel das berechnen.


    Hilft das etwas weiter?


    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  3. #3
    Hanno ist offline Neuer Benutzer
    Registriert seit
    21.01.2010
    Beiträge
    26

    Standard

    Hi,
    Vielen Dank schon einmal für deine Antwort.
    Also Window-Functions sagt mir nicht so wirklich viel, deshalb steh ich jetzt gerade auch ein wenig auf dem Schlauch und weiss nicht genau wie die Abfrage funktioniert.

    Vielleicht als Hinweis: Ich nutze PostgreSQL 8.3. Gibt es da vielleicht empfehlenswerte Literatur wo ich einmal nachschlagen könnte?

    Gruss
    Hanno

  4. #4
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von Hanno Beitrag anzeigen
    Hi,
    Vielen Dank schon einmal für deine Antwort.
    Also Window-Functions sagt mir nicht so wirklich viel, deshalb steh ich jetzt gerade auch ein wenig auf dem Schlauch und weiss nicht genau wie die Abfrage funktioniert.

    Vielleicht als Hinweis: Ich nutze PostgreSQL 8.3. Gibt es da vielleicht empfehlenswerte Literatur wo ich einmal nachschlagen könnte?

    Gruss
    Hanno
    Dieses Feature gibt es erst ab 8.4. Literatur? einiges, Google befragen...

    akretschmer's cte Bookmarks on Delicious


    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  5. #5
    Hanno ist offline Neuer Benutzer
    Registriert seit
    21.01.2010
    Beiträge
    26

    Standard

    Könnte man dann das Ganze in einer eigenen Aggregat-Funktion schreiben?
    Sodass ich dann später immer nur schreiben muss "select trend(raumeinheit) from table" oder so ähnlich?
    Oder muss ich jetzt erstmal meine Datenbank updaten auf die neuste Version?
    Hast du da einen Tip für mich wie ich das nun am schlauesten anstellen kann?

    Gruss
    Hanno

  6. #6
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von Hanno Beitrag anzeigen
    Könnte man dann das Ganze in einer eigenen Aggregat-Funktion schreiben?
    Sodass ich dann später immer nur schreiben muss "select trend(raumeinheit) from table" oder so ähnlich?
    Oder muss ich jetzt erstmal meine Datenbank updaten auf die neuste Version?
    Hast du da einen Tip für mich wie ich das nun am schlauesten anstellen kann?

    Gruss
    Hanno
    Man kann das ganz sicher auch in 8.3 als eine Funktion schreiben, aber in 8.4 gehen halt viele Dinge angenehmer. Ist Deine Entscheidung.

    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  7. #7
    Hanno ist offline Neuer Benutzer
    Registriert seit
    21.01.2010
    Beiträge
    26

    Standard

    Hättest du dann vielleicht auch noch einen Tipp wie ich die Funktion hinbekommen kann?
    Als Anfänger ist das wahrscheinlich nicht so einfach und ich kann gerade nicht abschätzen ob das viel Aufwand ist. Theoretisch könnte ich das Ganze ja auch über PHP verarbeiten, aber mir scheint es irgendwie sinnvoller, wenn ich die Werte auch gleich aus der DB bekommen kann ohne danach noch viel rumrechnen zu müssen.

    Gruss
    Hanno

  8. #8
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von Hanno Beitrag anzeigen
    Hättest du dann vielleicht auch noch einen Tipp wie ich die Funktion hinbekommen kann?
    Als Anfänger ist das wahrscheinlich nicht so einfach und ich kann gerade nicht abschätzen ob das viel Aufwand ist. Theoretisch könnte ich das Ganze ja auch über PHP verarbeiten, aber mir scheint es irgendwie sinnvoller, wenn ich die Werte auch gleich aus der DB bekommen kann ohne danach noch viel rumrechnen zu müssen.

    Gruss
    Hanno
    Wenn Du einen Plan hast, wie es in PHP gehen könnte: Du hast die ganz normalen Kontrollstrukturen etc. auch on PL/PGSQL zur Verfügung.

    PostgreSQL: Documentation: Manuals: PostgreSQL 8.4: PL/pgSQL - SQL Procedural Language

    Von daher ist der Aufwand sicher nicht zu vernachlässigen, aber wohl nicht größer als in PHP, z.B.


    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  9. #9
    Hanno ist offline Neuer Benutzer
    Registriert seit
    21.01.2010
    Beiträge
    26

    Standard

    Hallo,

    Ich habe jetzt einmal versucht eine Funktion zu deklarieren. Leider bin ich da als Anfänger etwas in Schwierigkeiten.

    create or replace function test2(raum integer, OUT trend numeric) returns numeric as $$
    DECLARE
    faktor numeric := 1;
    wert record;
    BEGIN
    for wert in select datenwert,raumeinheit from test where raumeinheit=raum
    LOOP
    faktor := faktor * 0.5;
    trend := (faktor*wert.datenwert);
    END LOOP;
    END;
    $$ LANGUAGE plpgsql;

    Das macht natürlich noch nicht das was es soll, aber man muss ja klein anfangen.
    Jetzt wiess ich aber nicht genau wie ich es anstellen kann, dass mir für jeden Datenwert in der Tabelle der trend berechnet wird. trend:= faktor*wert.datenwert
    wenn ich dann z.B. select test2(raumeinheit) from test; versuche, dann wird mir immer nur der berechnete Wert mit dem letzten Eintrag in der Tabelle "test" ausgegeben und das für jeden Eintrag der DB.

    Gruss
    Hanno

  10. #10
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Dresden
    Beiträge
    5.472

    Standard

    Zitat Zitat von Hanno Beitrag anzeigen
    Jetzt wiess ich aber nicht genau wie ich es anstellen kann, dass mir für jeden Datenwert in der Tabelle der trend berechnet wird. trend:= faktor*wert.datenwert
    wenn ich dann z.B. select test2(raumeinheit) from test; versuche, dann wird mir immer nur der berechnete Wert mit dem letzten Eintrag in der Tabelle "test" ausgegeben und das für jeden Eintrag der DB.

    Gruss
    Hanno
    Wenn ich Dich richtig verstehe, willst Du mehr als eine Ergebniszeile zurückgeben, richtig?

    PostgreSQL: Documentation: Manuals: PostgreSQL 8.4: Control Structures

    Beachte das Beispiel in "38.6.1.2. RETURN NEXT and RETURN QUERY"

    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Aggregat Restmenge
    Von bernd.bast@monega.de im Forum SQL
    Antworten: 1
    Letzter Beitrag: 11.08.2011, 18:22
  2. Where auf Aggregat-Ergebnis
    Von keith im Forum SQL
    Antworten: 2
    Letzter Beitrag: 06.11.2008, 10:09
  3. Antworten: 5
    Letzter Beitrag: 27.06.2006, 08:49

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Links: Tobias Bauer - IT- und Funkdienstleistungen   -   Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen   -   Funkforum