Einzelnen Beitrag anzeigen

FredlFesl

Registriert seit: 19. Apr 2011
293 Beiträge
 
Delphi 2009 Enterprise
 
#3

AW: Self join und Abs()

  Alt 30. Aug 2011, 07:47
Die Abfrage läuft ewig. Ist der join zweier Tabellen per berechnetem Wert (Abs()) erlaubt?
Erlaubt ist alles, was nicht verboten ist. Wieso sollte das verboten sein?

Aber SQLite ist nicht gerade Performanceweltmeister.

Falls ID monoton steigend ist, würde ich die Abfrage zusätzlich mit "a.ID > b.ID" einschränken.
Welche Spalten sind mit einem Index versehen?

Wenn Du ausgehende (<0) mit eingehenden (>0) Buchungen korrelieren willst, würde ich nicht mit ABS arbeiten, sondern die Buchungswerte direkt vergleichen. Das ist genauer, denn deine Abfrage liefert auch die Buchungen, bei denen ein Geldbetrag X auf ein Konto Y eingegangen ist, und der gleiche Betrag bis zu 7 Tage später irgendwo abgegangen ist => Blödsinn.
SQL-Code:
Select * from
  buchungen as Ausgehend join
  buchungen as Eingehend
    on Ausgehend.Geldbetrag = -Eingehend.Geldbetrag -- Index kann nicht verwendet werden!

where Eingehend.ID>Ausgehend.ID
  and Ausgehend.Geldbetrag < 0
  and Eingehend.Buchungsdatum between Ausgehend.Buchungsdatum - 7 and Ausgehend.Buchungsdatum
Du könntest auch den Geldbetrag als Absolutwert speichern und ein zusätzliches Feld "BuchungsArt" einführen. Dort steht dann "Überweisung", "Einzahlung" etc. drin.
Darüber (und über den Geldbetrag) legst Du dann einen Index und verwendest diese Spalten als JOIN-Verknüpfung. Dann kann die DB die Indexe verwenden. So ist das nicht möglich und daher wird die Abfrage recht langsam sein.

SQL-Code:
Select * from
  buchungen as Ausgehend join
  buchungen as Eingehend
    on Ausgehend.Geldbetrag = Eingehend.Geldbetrag -- Index kann verwendet werden!

where Eingehend.ID>Ausgehend.ID
  and Ausgehend.Buchungsart = Ueberweisung
  and Eingehend.Buchungsart = Einzahlung
  and Eingehend.Buchungsdatum between Ausgehend.Buchungsdatum - 7 and Ausgehend.Buchungsdatum
Oder machst es noch anders:
Du führst zwei Spalten für den Geldbetrag: Ausgehend, Eingehend. Darüber legst Du jeweils einen Index und vergleichest dann Ausgehend mit Eingehend.

SQL-Code:
Select * from
  buchungen as Ausgehend join
  buchungen as Eingehend
    on Ausgehend.AusgehenderGeldbetrag = Eingehend.EingehenderGeldbetrag -- Index kann verwendet werden

where Eingehend.ID>Ausgehend.ID
  and Ausgehend.AusgehenderGeldbetrag < 0
  and Eingehend.Buchungsdatum between Ausgehend.Buchungsdatum - 7 and Ausgehend.Buchungsdatum
Das Bild hängt schief.
  Mit Zitat antworten Zitat