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

SQL Abfragen dauern ewig, Join Problem, Firebird

Dieses Thema im Forum "Firebird und Interbase" wurde erstellt von Meister_Knobi, 17 Dezember 2014.

  1. Meister_Knobi

    Meister_Knobi Aktiver Benutzer

    Hallo, ich glaube das ist das gleiche Problem wie in meinen Früheren Threads.

    Wenn ich meinem Firebird Server eine Anfrage schicke läuft die SQL so lange das ich nie auf das Ergebniss gewartet habe. nach 40 min habe ich das Programm kalt abgewürgt da auch das nicht mehr reagiert hat. Der Firebirdserver lief ohne Probleme weiter.

    Das ist meine Abfrage und so wie die Zeilen jetzt auskommentiert sind funktioniert sie auch:
    Code:
    SELECT
       k.Kundennr,
       b.BelegNr,
       b.BelegDat
       --bp.PosNr,
       --a.artikelNr,
       --g.F2 as Kostenstelle,
       --round(sum(case when b.BelegArt = "GU" then bp.Gesamt * -1 when b.BelegArt = "RE" then bp.Gesamt else 0 end),2) as Umsatz2014
    FROM
       Kunden k 
       left join Beleg b on k.KundenNr = b.AdressNr and extract(YEAR From b.BelegDat) = 2014
       --left join BelegPos bp on b.BelegNr = bp.BelegNr
       --left join artikel a on bp.ArtikelNr = a.ArtikelNr
       --left join gdidef g on g.W0 = a.SteuerVK and g.Satzart = "ST"
    where
       k.Fibukto = "424242"
    Group BY
       k.Kundennr,
       b.BelegNr,
       b.BelegDat;
       --bp.PosNr,
       --a.artikelNr,
       --Kostenstelle
    Wenn ich jetzt aber anfange die nächsten Zeilen wieder zu entkommentieren landet meine Abfrage vermutlich in einer Dauerscheife.

    Ich glaube die SQL funktioniert nicht da sich die bedingung des 2. Joins auf eine Ebenfalls per Join eingebundene Tabelle bezieht. Nur sehe ich keine Möglichkeit diese Verschachtelung zu umgehen, da ich verknüpfungen berücksichtigen muss die sich über 5 Tabellen erstecken.

    Ziel dieser Abfrage ist den Umsatz einer Bestimmten Kundengruppe (424242) bestimmter Artikel mit bestimmteten Steuerschlüssel (ca 10 Stk.) zu bestimmen.
     
    Zuletzt von einem Moderator bearbeitet: 17 Dezember 2014
  2. Distrilec

    Distrilec Datenbank-Guru

    Ich behaupte einfach mal das hier macht das selbe wie dein Select (Kann es halt nicht testen :) ):
    Code:
    Select f.kundennr,
           f.belegnr,
           f.belegdat,
           f.posnr,
           f.artikelnr,
           g.f2 As kostenstelle,
           round(Sum(Case
                        When f.belegart = 'GU' Then
                         f.gesamt * -1
                        When f.belegart = 'RE' Then
                         f.gesamt
                        Else
                         0
                     End), 2) As "umsatz2014"
    From   (Select t.*,
                   a.artikelnr,
                   a.steuervk
            From   (Select b.*,
                           bp.posnr,
                           bp.gesamt
                    From   (Select k.kundennr,
                                   b.belegnr,
                                   b.belegdat,
                                   b.belegart
                            From   (Select k.kundennr
                                    From   kunden
                                    Where  fibukto = '424242') k
                            Left   Join beleg b
                            On     k.kundennr = b.adressnr
                            And    extract(Year From b.belegdat) = 2014) b
                    Left   Join belegpos bp
                    On     b.belegnr = bp.belegnr) t
            Left   Join artikel a
            On     t.artikelnr = a.artikelnr) f
    Left   Join gdidef g
    On     g.w0 = f.steuervk
    And    g.satzart = 'ST'
    Group  By f.kundennr,
              f.belegnr,
              f.belegdat,
              f.posnr,
              f.artikelnr,
              kostenstelle;
    Vorausgesetzt deine Bedingungen stimmen auch... Auch wenn ich glaube dass da der Fehler ist.
    Code:
    On     k.kundennr = b.adressnr
    Noch nie gehört das ne Adressnummer = Kundennummer sein soll ^^
     
    Meister_Knobi gefällt das.
  3. Meister_Knobi

    Meister_Knobi Aktiver Benutzer

    Ich weis das die stelle etwas komisch aussieht aber so ist tatsächlich die Verknüpfung, frag mich bitte nicht warum, ich habe die DB nicht erstellt^^

    Danke für den Code, werde ich nachher mal ausprobieren.
     
  4. Meister_Knobi

    Meister_Knobi Aktiver Benutzer

    Der Code funktioniert leider nicht. Meines verstätnisses nach müssten die Abfragen ja von Innen Nach außen trozdem Funktionieren. Die Innerste Abfrage muste ich etwas abändern da es ansonsten garnicht funktioniert hat.
    Code:
    Select kundennr
    From  kunden
    Where  fibukto = '424242'
    
    ich musste den Tabellenalias entfernen.
    die zweite ebene hat noch funktioniert
    Code:
    Select k.kundennr,
        b.belegnr,
        b.belegdat,
        b.belegart
    From  (Select kundennr
         From  kunden
         Where  fibukto = '424242') k
    Left  Join beleg b
    On  k.kundennr = b.adressnr
    And  extract(Year From b.belegdat) = 2014
    
    Ab der 3. Ebene versagt aber der Code und bei mir stürzen sämtliche Programme ab, mit denen ich die SQL ausführe.
    Code:
    Select b.*,
        bp.posnr,
        bp.gesamt
    From  (Select k.kundennr,
            b.belegnr,
            b.belegdat,
            b.belegart
         From  (Select kundennr
             From  kunden
             Where  fibukto = '424242') k
         Left  Join beleg b
         On  k.kundennr = b.adressnr
         And  extract(Year From b.belegdat) = 2014) b
    Left  Join belegpos bp
    On  b.belegnr = bp.belegnr
    
    Da ich keine Fehlermeldung erhalte bin ich ziemlich ratlos.

    Mit den Beschriebenen änderungen habe ich dann mal den gesamten Code abgeschikt.
    Code:
    Select f.kundennr,
      f.belegnr,
      f.belegdat,
      f.posnr,
      f.artikelnr,
      g.f2 As kostenstelle,
      round(Sum(Case
      When f.belegart = 'GU' Then
      f.gesamt * -1
      When f.belegart = 'RE' Then
      f.gesamt
      Else
      0
      End), 2) As umsatz2014
    From  (Select t.*,
      a.artikelnr,
      a.steuervk
      From  (Select b.*,
      bp.posnr,
      bp.gesamt
      From  (Select k.kundennr,
      b.belegnr,
      b.belegdat,
      b.belegart
      From  (Select kundennr
      From  kunden
      Where  fibukto = '155000') k
      Left  Join beleg b
      On  k.kundennr = b.adressnr
      And  extract(Year From b.belegdat) = 2014) b
      Left  Join belegpos bp
      On  b.belegnr = bp.belegnr) t
      Left  Join artikel a
      On  t.artikelnr = a.artikelnr) f
    Left  Join gdidef g
    On  g.w0 = f.steuervk
    And  g.satzart = 'ST'
    Group  By f.kundennr,
      f.belegnr,
      f.belegdat,
      f.posnr,
      f.artikelnr,
      kostenstelle;
    
    Als erstes hat mir das Programm den Spaltenalias "Umsatz2014" bemängelt. Mein Firebird 2.5 server scheint aber Aliase in Quots nicht zu akzeptieren. Ist mir aber schon früher aufgefallen. Danach beschwert er sich über die Zeile 34 mit dieser Fehlermeldung
    Code:
    Engine Code  : 335544569
    Engine Message :
    Dynamic SQL Error
    SQL error code = -206
    Column unknown
    T.ARTIKELNR
    At line 34, column 18
    
     
  5. Distrilec

    Distrilec Datenbank-Guru

    Oh, entschuldige... Habe das ganz einfach händisch eingetippt und zum Teil auch einfach c&p benutzt... Mann ist ja faul ^^ Kann sein das mir da ein paar Fehler reingelaufen sind (Wie gesagt... Kann es ja, mangels Tabellen, nicht ausprobieren). Die Anführungszeichen bei umsatz2014 brauch man nicht, ist nur eine Angewohnheit Zahlen in Spaltenbezeichnungen in Anführungszeichen zu setzen.

    EDIT:
    Probier mal das.
    Code:
    Select f.kundennr,
           f.belegnr,
           f.belegdat,
           f.posnr,
           f.artikelnr,
           g.f2 As kostenstelle,
           round(Sum(Case
                        When f.belegart = 'GU' Then
                         f.gesamt * -1
                        When f.belegart = 'RE' Then
                         f.gesamt
                        Else
                         0
                     End), 2) As umsatz2014
    From   (Select t.*,
                   a.artikelnr,
                   a.steuervk
            From   (Select b.*,
                           bp.posnr,
                           bp.artikelnr
                           bp.gesamt
                    From   (Select k.kundennr,
                                   b.belegnr,
                                   b.belegdat,
                                   b.belegart
                            From   (Select kundennr
                                    From   kunden
                                    Where  fibukto = '155000') k
                            Left   Join beleg b
                            On     k.kundennr = b.adressnr
                            And    extract(Year From b.belegdat) = 2014) b
                    Left   Join belegpos bp
                    On     b.belegnr = bp.belegnr) t
            Left   Join artikel a
            On     t.artikelnr = a.artikelnr) f
    Left   Join gdidef g
    On     g.w0 = f.steuervk
    And    g.satzart = 'ST'
    Group  By f.kundennr,
              f.belegnr,
              f.belegdat,
              f.posnr,
              f.artikelnr,
              kostenstelle;
    
     
    Meister_Knobi und Walter gefällt das.
  6. Meister_Knobi

    Meister_Knobi Aktiver Benutzer

    Fehler passieren, danke für deine Hilfe. auch wenn ich im Monemt garkein Ergebnis habe habe ich wenigestens das Gefühl als das ich nur noch 2 - 3 kl bugs vom Wunschergebins etfehrnt bin.

    Ich habe deinen Code Ausprobiert und jetzt sagt er mir das Innerhalb der Tabelle F die ArtikelNr mehrfach definiert ist. also habe ich die Zeile "a.artikelnr," entfehrnt nun aber stürzt FlameRobin wieder ab. eigentlich auch klar wenn er damit den Bezugspunkt des LeftJoin verliert. Nur weiß ich nicht wie wo artikelnr innerhalb von f noch verhanden sein soll.
     
  7. Hony%

    Hony% Datenbank-Guru

    Warum sollte das passieren? Die Projektion (SELECT) findet grundsätzlich als letztes statt. Also nachdem der JOIN durchgeführt wurde.

    Vermutlich wirst du du den Fehler deutlich schneller finden wenn du von innen angefangen die verschachtelten SELECTS und JOINS in eigene VIEWS auslagerst. Dadurch wird die Abfrage Stück für Stück übersichtlicher und du merkst sofort an welcher Stelle die Probleme auftreten.
     
  8. akretschmer

    akretschmer Datenbank-Guru

    Gibt es kein Explain?
     
  9. Meister_Knobi

    Meister_Knobi Aktiver Benutzer

    Ich bin ein Fan vom Übersichtlichen. Nur höre ich jetzt zum esrten mal von einem VIEW. Habe ich noch nie mit gearbeitet, und ja meine Schule war total sch*, da wir hier aber über Firebird reden, sch%.
     
  10. Meister_Knobi

    Meister_Knobi Aktiver Benutzer

    Bin ich jetzt blöder als sonst oder gibs wirklich keinen bearbeiten Button? Dann wirds ein 2. Post sry

    Ich komm nicht mehr so wirklich weiter mit der Abfrage, SQL hab ich nie richtig gelernt und unser, ich nenn ihn mal Datenbank Dienstleister, hat im Moment nur wenig bis keine Zeit.
    Könnten wir uns auf den Code konzentrieren? Ich habe leider keine Zeit mit grosartig mit neuen Sachen zu beschäftigen. Tut mir leid wegen dem gebettel aber mir steht das Wasser bis zum Hals.
     
  11. Distrilec

    Distrilec Datenbank-Guru

    Code:
    Create View vw_kunden As
    Select k.Kundennr,
           b.BelegNr,
           b.BelegDat,
           b.BelegArt
    From   kunden k
    Left   Join beleg b
    On     k.kundennr = b.adressnr
    And    extract(Year From b.belegdat) = 2014;
    
    Create View vw_belegpos As
    Select b.*,
           bp.PosNr,
           bp.ArtikelNr
    From   vw_kunden b
    Left   Join belegpos bp
    On     b.belegnr = bp.belegnr;
    
    Create View vw_artikel As
    Select t.*,
           a.SteuerVK
    From   vw_belegpos t
    Left   Join artikel a
    On     t.artikelnr = a.artikelnr;
    
    Select f.kundennr,
           f.belegnr,
           f.belegdat,
           f.posnr,
           f.artikelnr,
           g.f2 As kostenstelle,
           round(Sum(Case
                        When f.belegart = 'GU' Then
                         f.gesamt * -1
                        When f.belegart = 'RE' Then
                         f.gesamt
                        Else
                         0
                     End), 2) As umsatz2014
    From   vw_artikel f
    Left   Join gdidef g
    On     g.w0 = f.SteuerVK
    And    g.satzart = 'ST'
    Group  By f.kundennr,
              f.belegnr,
              f.belegdat,
              f.posnr,
              f.artikelnr,
              kostenstelle;
    Ausführen... Auf Fehler warten... Fehlercode posten... Auf meine Antwort warten... Oderso :)
     
    Meister_Knobi gefällt das.
  12. Meister_Knobi

    Meister_Knobi Aktiver Benutzer

    Ich kann dem Code jetzt nicht mehr folgen. Da Create darin vorkommt habe ich den Code jetzt besser auf einer Kopie der DB ausgeführt. Hier der Fehler:

    Code:
    Error: *** IBPP::SQLException ***
    Context: Statement::Prepare(
    
    Select f.kundennr,
      f.belegnr,
      f.belegdat,
      f.posnr,
      f.artikelnr,
      g.f2 As kostenstelle,
      round(Sum(Case
      When f.belegart = 'GU' Then
      f.gesamt * -1
      When f.belegart = 'RE' Then
      f.gesamt
      Else
      0
      End), 2) As umsatz2014
    From  vw_artikel f
    Left  Join gdidef g
    On  g.w0 = f.SteuerVK
    And  g.satzart = 'ST'
    Group  By f.kundennr,
      f.belegnr,
      f.belegdat,
      f.posnr,
      f.artikelnr,
      kostenstelle )
    Message: isc_dsql_prepare failed
    
    SQL Message : -204
    can't format message 13:796 -- message file C:\Programme\firebird.msg not found
    
    Engine Code  : 335544569
    Engine Message :
    Dynamic SQL Error
    SQL error code = -204
    Table unknown
    VW_ARTIKEL
    At line 17, column 19
     
  13. Distrilec

    Distrilec Datenbank-Guru

    Code:
    SQL error code = -204
    Table unknown
    VW_ARTIKEL
    At line 17, column 19
    Anscheinend hast du die View nicht created ?
    Ansonsten gäbe es kein table unknown error.

    Create-Statements einfach von oben nach unten ausführen und dann erst das Select... :)
     
  14. Meister_Knobi

    Meister_Knobi Aktiver Benutzer

    Ok hatte ich eigentlich gemacht. Beim 2. mal kam eine andere Meldung. ich nutze FlameRobin und habe die Funktion "run querry..." genutzt.

    Jetzt erhalte ich diese antwort:
    Code:
    Starting transaction...
    Preparing query: Create View vw_kunden As
    Select k.Kundennr,
      b.BelegNr,
      b.BelegDat,
      b.BelegArt
    From  kunden k
    Left  Join beleg b
    On  k.kundennr = b.adressnr
    And  extract(Year From b.belegdat) = 2014
    Prepare time: 0.047s
    Plan not available.
    
    
    Executing...
    Error: *** IBPP::SQLException ***
    Context: Statement::Execute( Create View vw_kunden As
    Select k.Kundennr,
      b.BelegNr,
      b.BelegDat,
      b.BelegArt
    From  kunden k
    Left  Join beleg b
    On  k.kundennr = b.adressnr
    And  extract(Year From b.belegdat) = 2014 )
    Message: isc_dsql_execute2 failed
    
    SQL Message : -607
    can't format message 13:393 -- message file C:\Programme\firebird.msg not found
    
    Engine Code  : 335544351
    Engine Message :
    unsuccessful metadata update
    STORE RDB$RELATION_FIELDS failed
    attempt to store duplicate value (visible to active transactions) in unique index "RDB$INDEX_15"
    
    
    Total execution time: 10.064s
     
  15. Distrilec

    Distrilec Datenbank-Guru

    Die View vm_kunden scheint er bereits angelegt zu haben...
    Versuch mal die anderen durch (und ignorier dabei den Fehlercode -607, sollte er auftreten)

    EDIT:
    Versuchs mal so
    Code:
    Create View vw_kunden(kundennr, belegnr, belegdat, belegart) As
    Select k.kundennr,
           b.belegnr,
           b.belegdat,
           b.belegart
    From   kunden k
    Left   Join beleg b
    On     k.kundennr = b.adressnr
    And    extract(Year From b.belegdat) = 2014;
    
    Create View vw_belegpos(kundennr, belegnr, belegdat, belegart, posnr, artikelnr) As
    Select b.*,
           bp.posnr,
           bp.artikelnr
    From   vw_kunden b
    Left   Join belegpos bp
    On     b.belegnr = bp.belegnr;
    
    Create View vw_artikel(kundennr, belegnr, belegdat, belegart, posnr, artikelnr, steuervk) As
    Select t.*,
           a.steuervk
    From   vw_belegpos t
    Left   Join artikel a
    On     t.artikelnr = a.artikelnr;
    
    Select f.kundennr,
           f.belegnr,
           f.belegdat,
           f.posnr,
           f.artikelnr,
           g.f2 As kostenstelle,
           round(Sum(Case
                        When f.belegart = 'GU' Then
                         f.gesamt * -1
                        When f.belegart = 'RE' Then
                         f.gesamt
                        Else
                         0
                     End), 2) As umsatz2014
    From   vw_artikel f
    Left   Join gdidef g
    On     g.w0 = f.steuervk
    And    g.satzart = 'ST'
    Group  By f.kundennr,
              f.belegnr,
              f.belegdat,
              f.posnr,
              f.artikelnr,
              kostenstelle;
     
Die Seite wird geladen...

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