1. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

FireBirdSQL Maximumwerte

Dieses Thema im Forum "Firebird und Interbase" wurde erstellt von Meister_Knobi, 19 März 2015.

  1. Meister_Knobi

    Meister_Knobi Aktiver Benutzer

    Hallo,

    meine Frage bezieht sich eigentlich auf FirebirdSQL aber aus dem InternetTM habe ich das die Syntax sich ziemlich ähnelt.

    Ich habe das Problem das ich zu Kunden nach Datum die Letzten beiden Notizen aus der DB zeihn möchte. Ich schaffe es leider nur das Letzte datum einer Notiz zusammen mit dem Kunden ausgeben zu lassen. Sobalt ich aber die Notiz selber mit ausgeben möchte erhalte ich alle Notizen.

    Dazu habe ich noch überhaupt keine idee wie ich das 2. größe datum als 3 bzw 4 Spalte in die Ausgabe bekomme.
    hier mein Code:
    Code:
    SELECT
       K.KundenNr,
       max(getdate(n1.createdate))
    From
       Kunden k
       LEFT JOIN Notiz n1 on k.Adressnr = n1.AdressNr
    Group by
       K.KundenNr
    
    Jedes weitere Feld aus der Kundentabelle kein Problem aber ein weiteres aus der Notiztabelle und das max() verliert seine wirkung, auch mit der bedinung where n1.createdate=max(n1.createdate)

    ich komme da überhaupt nicht mehr vorran.
     
  2. Meister_Knobi

    Meister_Knobi Aktiver Benutzer

    Hello again,

    ich bin soweit gekommen das ich jetzt die Letzte Notiz mit einem Kunden verbinden kann. Jedoch fehlt mir noch die 2. letzte Notiz des Kunden.

    Code:
    Select
       k.Kundennr,
       k.Name1,
       n2.AdressNr,
       n2.Text As Notiz,
       n2.Createdate as Datum
    From
       Kunden k
    Left Join
       Notiz n2
    On
       k.Adressnr = n2.adressnr
    Inner Join
       (SELECT Letzte_Notiz_von_Kunde.AdressNr, max(Letzte_Notiz_von_Kunde.CreateDate) as Letztes_Datum From Notiz Letzte_Notiz_von_Kunde Group By Letzte_Notiz_von_Kunde.AdressNr) as n3
    ON
       n2.AdressNr = n3.AdressNr
       and n2.Createdate = n3.Letztes_Datum
    
    Um das 2. letzte datum zu bestimmen nehme ich an muss ich erst das höchste datum bestimmen, was ich hier ja schon getan habe. Ich weiß jetzt nicht ob ich hier ein weiteres Left Join auf die Kundentabelle brauche oder ob ich das mit dem Inner join verbinden kann.
     
  3. akretschmer

    akretschmer Datenbank-Guru

    M$SQL kann doch schon Window-Funktionen, oder? Damit wäre das recht generisch lösbar.
     
  4. akretschmer

    akretschmer Datenbank-Guru

    Ich seh grad, Du hast Firebird (?). Also, kann das Window-Funktionen? Ist so exotisch ...
     
  5. Meister_Knobi

    Meister_Knobi Aktiver Benutzer

    Ich glaube nicht das FBDB spezielle Windowsfunktionen unterstützt, ist meine ich eigentlich platform unabhäning. Werde mal versuchen ein 2. LeftJoin zu basteln. Ich werde erst wieder die Maximumwerte bestimmen, diese dann bei einer 2. Bestimmung des Maximum ausschließen. Und dann so weitermachen wie bisher.

    Gibt es die möglichkeit einer Skalierbaren lösung? Also ich hab den Parameter :Anzahl_der_letzten_Notizen o.ä. und anhand von dem Simpel die Anzahl der sich in den Spalten aufbauenden Notizen bestimmen kann? Wegenmeiner auch in MSSQL oder MySQL. Muss dann nur versuchen die Syntax zu übersetzten.
     
  6. Distrilec

    Distrilec Datenbank-Guru

    Ich glaube mit Window-Funktionen meinter @akretschmer die Window-Clause von Aggregationen... Keine Funktionalität von Windows (OS) :D
    a.k.a. Analytic Functions
     
  7. Meister_Knobi

    Meister_Knobi Aktiver Benutzer

    Ja, das war mir schon klar das er sich auf MSSQL beziht und nicht auf WindowsNT^^ Es ist noch früh am Mogeren und mein Hirn bootet noch. Da passieren fehler^^
     
  8. akretschmer

    akretschmer Datenbank-Guru

    Um das mal zu zeigen, zuerst basten wir uns eine Tabelle:

    Code:
    test=*# create table notizen as select id, nr, x from (select * from generate_Series(1,5) id) bla cross join (select nr, random() x from generate_series(1,5) nr) foo;
    SELECT 25   
    Time: 1,148 ms   
    test=*# select * from notizen ;   
     id | nr |  x   
    ----+----+-------------------   
      1 |  1 | 0.452331696636975   
      1 |  2 | 0.545575194992125   
      1 |  3 | 0.784099191892892   
      1 |  4 | 0.329756254795939   
      1 |  5 | 0.266754880547523   
      2 |  1 | 0.452331696636975   
      2 |  2 | 0.545575194992125   
      2 |  3 | 0.784099191892892   
      2 |  4 | 0.329756254795939   
      2 |  5 | 0.266754880547523   
      3 |  1 | 0.452331696636975   
      3 |  2 | 0.545575194992125   
      3 |  3 | 0.784099191892892   
      3 |  4 | 0.329756254795939   
      3 |  5 | 0.266754880547523   
      4 |  1 | 0.452331696636975   
      4 |  2 | 0.545575194992125   
      4 |  3 | 0.784099191892892   
      4 |  4 | 0.329756254795939   
      4 |  5 | 0.266754880547523   
      5 |  1 | 0.452331696636975   
      5 |  2 | 0.545575194992125   
      5 |  3 | 0.784099191892892   
      5 |  4 | 0.329756254795939   
      5 |  5 | 0.266754880547523   
    (25 rows)   
    
    Nun fragen wir die nochmals ab, zählen aber je id und geordnet nach nr die Zeilen:

    Code:
    test=*# select id, nr, x, row_number() over (partition by id order by nr asc) from notizen ;
     id | nr |  x  | row_number   
    ----+----+-------------------+------------   
      1 |  1 | 0.452331696636975 |  1   
      1 |  2 | 0.545575194992125 |  2   
      1 |  3 | 0.784099191892892 |  3   
      1 |  4 | 0.329756254795939 |  4
      1 |  5 | 0.266754880547523 |  5
      2 |  1 | 0.452331696636975 |  1
      2 |  2 | 0.545575194992125 |  2
      2 |  3 | 0.784099191892892 |  3
      2 |  4 | 0.329756254795939 |  4
      2 |  5 | 0.266754880547523 |  5
      3 |  1 | 0.452331696636975 |  1
      3 |  2 | 0.545575194992125 |  2
      3 |  3 | 0.784099191892892 |  3
      3 |  4 | 0.329756254795939 |  4
      3 |  5 | 0.266754880547523 |  5
      4 |  1 | 0.452331696636975 |  1
      4 |  2 | 0.545575194992125 |  2
      4 |  3 | 0.784099191892892 |  3
      4 |  4 | 0.329756254795939 |  4
      4 |  5 | 0.266754880547523 |  5
      5 |  1 | 0.452331696636975 |  1
      5 |  2 | 0.545575194992125 |  2
      5 |  3 | 0.784099191892892 |  3
      5 |  4 | 0.329756254795939 |  4
      5 |  5 | 0.266754880547523 |  5
    (25 rows)
    
    Wenn wir nun je id nur die 2 ersten Datensätze wollen tüteln wir das in ein Subselect und bauen außen ein WHERE ein:

    Code:
    test=*# select id, nr, x from (select id, nr, x, row_number() over (partition by id order by nr asc) from notizen ) bla where row_number <= 2;
     id | nr |  x
    ----+----+-------------------
      1 |  1 | 0.452331696636975
      1 |  2 | 0.545575194992125
      2 |  1 | 0.452331696636975
      2 |  2 | 0.545575194992125
      3 |  1 | 0.452331696636975
      3 |  2 | 0.545575194992125
      4 |  1 | 0.452331696636975
      4 |  2 | 0.545575194992125
      5 |  1 | 0.452331696636975
      5 |  2 | 0.545575194992125
    (10 rows)
    
    Die Sortierung nun absteigend zu machen und/oder nicht 2 sondern 3 Elemente zu holen überlasse ich Dir zur Übung ;-)
     
  9. Meister_Knobi

    Meister_Knobi Aktiver Benutzer

    Darauf binich nicht gekommen, die Dinger zu Nummerieren,... für mich zu simpel um selber drauf zu kommen. nur das jetzt in FB SQL zu übersetzten hapert es bei mir. Fängt schon an das ich nen ersatz für die Funktion row_number bekomme. Das einzige was ich gefunden habe ist bis jetzt row_count aber das hat eine andere funktion.
     
  10. akretschmer

    akretschmer Datenbank-Guru

    Ja, das ist wohl auch die einfachste Window-Funktion. Es gibt noch einige andere, mit denen man viel Unfug (und auch nützlche Dinge) machen kann.
     
  11. Meister_Knobi

    Meister_Knobi Aktiver Benutzer

    Ich finde ja Windows ist unfug ;) aber lassen wir das Thema besser ruhen.

    Ich habe meine Abfrage jetzt so erweitert das Sie mir zumindest schonmal 2 Notizen liefert, nur leider 2 mal die gleiche^^

    Code:
    Select
       k.Kundennr,
       k.Name1,
       n2.AdressNr,
       n2.Text As Notiz,
       n2.Createdate as Datum,
       nTop2.createdate,
       nTop2.Text as Notiz2   
    From
       Kunden k
    Left Join
       Notiz n2
       On
         k.Adressnr = n2.adressnr
    Inner Join
       (SELECT Letzte_Notiz_von_Kunde.AdressNr, max(Letzte_Notiz_von_Kunde.CreateDate) as Letztes_Datum From Notiz Letzte_Notiz_von_Kunde Group By Letzte_Notiz_von_Kunde.AdressNr) as n3
       ON
         n2.AdressNr = n3.AdressNr
         and n2.Createdate = n3.Letztes_Datum
    Left Join
       Notiz ntop2
       On
         k.Adressnr = ntop2.adressnr
    Inner Join
       (Select Max2.AdressNr, max(Max2.CreateDate) as Top2_Datum From Notiz Max2 Group By Max2.AdressNr) as Top2
       On
         ntop2.Adressnr = Top2.AdressNr
         and nTop2.Createdate = Top2.Top2_Datum
    Left Outer Join
       (SELECT Max1.AdressNr, max(Max1.CreateDate) as Top1_Datum From Notiz Max1 Group By Max1.AdressNr) as Top1
       ON
         Top2.AdressNr = Top1.AdressNr
         and Top2.Top2_Datum = Top1.Top1_Datum
    
     

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden