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

Thema: Aggregatfunktion mit sortierung

  1. #1
    Registriert seit
    06.10.2006
    Beiträge
    44

    Standard Aggregatfunktion mit sortierung

    Ich habe eine Tabelle mit folgenden Struktur:

    id
    article_id
    sort
    key
    value

    zu einer article_id gibt es mehrere key/value Paare.
    Ich möchte das ganze in folgender Form ausgeben:

    article_id, key, value, key, value , ...
    wobei die key/value Tupel entspechend der spalte sort sortiert sind.

    Ich habe eine einfache Aggregatfunktion erstellt, welche die key/value Paare in ein Array schreibt, dieses wird dann am Ende wieder in einen String umwandelt, aber sobald ich die sort Spalte mit in das select einbaue, muss es auch im group by stehen und dann habe ich immer nur ein Tupel im Array.

    hat jemand eine Idee , wie man das hinbekommt?
    rolf

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

    Standard

    Zitat Zitat von rolf.schaufelberger Beitrag anzeigen
    Ich habe eine Tabelle mit folgenden Struktur:

    id
    article_id
    sort
    key
    value

    zu einer article_id gibt es mehrere key/value Paare.
    Wie viele?

    Ich möchte das ganze in folgender Form ausgeben:

    article_id, key, value, key, value , ...
    wobei die key/value Tupel entspechend der spalte sort sortiert sind.
    Wieviel kommt nach dem ... ?
    Schaut nach einer wilden Kreutztabelle aus.

    Ich habe eine einfache Aggregatfunktion erstellt, welche die key/value Paare in ein Array schreibt, dieses wird dann am Ende wieder in einen String umwandelt, aber sobald ich die sort Spalte mit in das select einbaue, muss es auch im group by stehen und dann habe ich immer nur ein Tupel im Array.

    hat jemand eine Idee , wie man das hinbekommt?
    rolf
    nicht wirklich.

    Zeig mal ein Beispiel für die Daten und wie das Result aussehen soll. Mit plpgsql kann man viel machen...

    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
    castorp ist offline Erfahrener Benutzer
    Registriert seit
    27.06.2009
    Beiträge
    525

    Standard

    Wie wäre es damit:
    Code:
    SELECT article_id, 
           array_to_string(keys, ', ')
    FROM (
      SELECT article_id, 
             array_agg(key||'='||value) OVER (PARTITION BY article_id ORDER BY sort) as keys,
             row_number() OVER (PARTITION BY article_id ORDER BY sort DESC) as row_number
      FROM articles
    ) t
    WHERE row_number = 1

  4. #4
    Registriert seit
    06.10.2006
    Beiträge
    44

    Standard

    Zitat Zitat von akretschmer Beitrag anzeigen
    Wie viele?
    Theoretisch kann es beliebig viele dieser key/value Tupel geben,
    allerdings sind es immer gleich viele.

    Zitat Zitat von akretschmer Beitrag anzeigen
    Wieviel kommt nach dem ... ?
    Schaut nach einer wilden Kreutztabelle aus.
    Nein nein, es gibt zu einen Artikel (refernziert durch den Fk article_id) eine Reihe von Merkmalen, die über key/value Tupel spezifiziert werden. Die sort Spalte dient dazu, die Reienfolge im GUI zu bestimmen.

    Zitat Zitat von akretschmer Beitrag anzeigen
    Zeig mal ein Beispiel für die Daten und wie das Result aussehen soll. Mit plpgsql kann man viel machen...
    das ist nicht so einfach, da im wirklichen Fall noch ein paar Tabellen mehr involviert sind. Dann habe ich in der Doku nichts darüber gefunden, wie genau eine eigene sfunc in create aggreate aufgebaut sein muss, speziell was den Rückgabewert betrifft.
    Ich versuche mal, das auf das Kernproblem zu reduzieren.
    Rolf



    Andreas

  5. #5
    Registriert seit
    06.10.2006
    Beiträge
    44

    Standard

    uhh was ist das Over? partition ?
    Noch nie gesehen, Ist das neu am 8.4 ?
    Ich habe hier noch 8.3 am Laufen.

  6. #6
    castorp ist offline Erfahrener Benutzer
    Registriert seit
    27.06.2009
    Beiträge
    525

    Standard

    Zitat Zitat von rolf.schaufelberger Beitrag anzeigen
    uhh was ist das Over? partition ?
    Noch nie gesehen, Ist das neu am 8.4 ?
    Ich habe hier noch 8.3 am Laufen.
    Ja, ist 8.4
    Nachdem Du keine Version erwähnt hast, bin ich davon ausgegangen, dass Du die aktuelle verwendest.

    Zur Syntax:
    PostgreSQL: Documentation: Manuals: PostgreSQL 8.4: Window Functions

  7. #7
    Registriert seit
    06.10.2006
    Beiträge
    44

    Standard

    Zitat Zitat von castorp Beitrag anzeigen
    Wie wäre es damit:
    Code:
    SELECT article_id, 
           array_to_string(keys, ', ')
    FROM (
      SELECT article_id, 
             array_agg(key||'='||value) OVER (PARTITION BY article_id ORDER BY sort) as keys,
             row_number() OVER (PARTITION BY article_id ORDER BY sort DESC) as row_number
      FROM articles
    ) t
    WHERE row_number = 1
    Ahh, Junge, das passt, das ist aber schon heftig in die Trickkiste gegriffen, so spontan fällt einem das nicht ein! Ich musste es noch etwas ändern damit es mit meinen Tabellen passt, aber das Ergebnis sieht gut aus. Jetzt muss ich noch die halbe Nacht Doku lesen um zu verstehen, warum das funktioniert ...

  8. #8
    castorp ist offline Erfahrener Benutzer
    Registriert seit
    27.06.2009
    Beiträge
    525

    Standard

    Zitat Zitat von rolf.schaufelberger Beitrag anzeigen
    Ahh, Junge, das passt, das ist aber schon heftig in die Trickkiste gegriffen, so spontan fällt einem das nicht ein!
    Kommt drauf an

    Wenn man mal Geschmack an den Windowing Functions gefunden hat, dann ist das immer das erste woran man denkt...

    Ich verwende die schon seit ewigen Zeiten gerne bei Oracle und war froh als meine Lieblings-DB das auch endlich konnte

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

    Standard

    Zitat Zitat von castorp Beitrag anzeigen
    Kommt drauf an

    Wenn man mal Geschmack an den Windowing Functions gefunden hat, dann ist das immer das erste woran man denkt...

    Ich verwende die schon seit ewigen Zeiten gerne bei Oracle und war froh als meine Lieblings-DB das auch endlich konnte
    Hey, geil, wenn Du da Erfahrung hast, ich hab da noch so meine Probleme dann und wann damit ...

    Sag mal, wie geht sowas:
    Code:
    test=*# select * from bla;
     id | val
    ----+-----
      1 |   3
      2 |   2
      3 |   1
      4 |   5
      5 |   5
    (5 Zeilen)
    Ich möchte da nun ein 'gleitendes' Fenster haben und die Summe bilden:

    Code:
    1 | 3
    2 | 5
    3 | 3
    4 | 6
    5 | 10
    Also z.B. immer die Summe von val des aktuellen Record und dem davor. Oder Summe von val von Record davor, aktuell und danach.


    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

  10. #10
    castorp ist offline Erfahrener Benutzer
    Registriert seit
    27.06.2009
    Beiträge
    525

    Standard

    Zitat Zitat von akretschmer Beitrag anzeigen
    Also z.B. immer die Summe von val des aktuellen Record und dem davor. Oder Summe von val von Record davor, aktuell und danach.
    Das ist einfach

    Code:
    SELECT id,
           val,
           val + lag(val,1,0) over (order by id) as summe_mit_vorher,
           val + lag(val,1,0) + over (order by id) + lead(val, 1, 0) over (order by id) as summe_vorher_und_nachher
    FROM bla;
    lag() greift auf die "vorherige" row zu. Der erste parameter definiert die Spalte aus der Zeile. Der zweite parameter definiert wie weit man zurückgehen will (2 bedeutet 2 Zeilen zurück usw), der dritte Parameter der default wert, falls es diese Zeile nicht gibt (bei der ersten gibt es ja keinen Vorgänger.

    Erste/Vorherige usw. bezieht sich auf die Sortierung die in over() angegeben wurde.

    Mit negativen Werten für den zweiten Parameter geht man "vorwärts". Aber dafür kann man auch die lead() Funktion verwenden.

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Frage Aggregatfunktion, akkumulieren mit arrays
    Von george im Forum SQL
    Antworten: 4
    Letzter Beitrag: 09.12.2010, 11:42
  2. Umformatieren / Aggregatfunktion ??
    Von vollbotz im Forum SQL
    Antworten: 11
    Letzter Beitrag: 08.06.2010, 11:11
  3. Frage Aggregatfunktion (String Array)
    Von Shandrogar im Forum SQL
    Antworten: 2
    Letzter Beitrag: 31.05.2010, 18:25
  4. Problem Aggregatfunktion mit if
    Von kirberg im Forum SQL
    Antworten: 5
    Letzter Beitrag: 12.11.2008, 09:44
  5. Select mit Aggregatfunktion
    Von Harald im Forum SQL
    Antworten: 4
    Letzter Beitrag: 30.05.2008, 09:20

Stichworte

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