Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   FULL OUTER JOIN zeigt nicht alle records (https://www.delphipraxis.net/194231-full-outer-join-zeigt-nicht-alle-records.html)

MyRealName 31. Okt 2017 15:59

Datenbank: Firebird • Version: 3 • Zugriff über: UniDAC

FULL OUTER JOIN zeigt nicht alle records
 
Hallo,

hab ein seltsames Problem und bin am Rande der Verzweiflung, weil ich den Fehler nicht sehe.

Ich habe 2 Datenbanken, eine ist die aktuelle (mit der Tablelle GL und dem erzeugten Suffix _Loc) und die andere ist eine Kopie zu einem bestimmten Zeitpunkt. Das Programm kopiert die Daten der Kopie in die aktuelle DB in eine Hilfstabelle (GL_Ext). Dabei wird der Saldo (Debit-Credit) schon gebildet :

Code:
INSERT INTO GL_EXT (E, S, TIPO, NUMERO, SALDO, ACCT)
  SELECT E, S, Tipo, Batch, SUM(Debit-Credit), ACCT
  FROM GL
  WHERE Fecha BETWEEN '01/01/2016' AND '12/31/2016'
  GROUP BY E, S, Tipo, Batch, ACCT
Die Abfrage soll nun herausfinden, wo der Saldo anders ist pro Dokument (Felder E, S, Tipo und Numero/Batch) und Account Nummer (ACCT).
Dabei können die folgenden Fälle eintreten :

1. In beiden is der Saldo gleich
2. In einem der beiden ist der Saldo anders, aber E, S, Tpo, Numero, ACCT ist vorhanden
3. Auf der Rechten Seite fehlt ein Dokument (teilweise oder gänzlich), welches auf der linken Seite vorhanden ist
4. Auf der linken Seite (GL) fehlt ein Dokument (teilweise oder gänzlich), welches auf der rechten Seite vorhanden ist


Code:
SELECT A.E_Loc, A.S_Loc, A.Tipo_Loc, A.Numero_Loc, A.Saldo_Loc, A.E_Ext, A.S_Ext, A.Tipo_Ext, A.Numero_Ext, A.Saldo_Ext, A.Acct
FROM (SELECT G.ACCT,
             G.E E_Loc, G.S S_Loc, G.Tipo Tipo_Loc, G.Batch Numero_Loc, CAST(SUM(G.Debit-G.Credit) AS Currency) Saldo_Loc,
             GE.E E_Ext, GE.S S_Ext, GE.Tipo Tipo_Ext, GE.Numero Numero_Ext, COALESCE(GE.Saldo, 0) Saldo_Ext
      FROM GL G
      FULL JOIN GL_EXT GE ON (GE.E=G.E AND GE.S=G.S AND GE.Tipo=G.Tipo AND GE.Numero=G.Batch AND GE.Acct=G.Acct)
      WHERE G.Fecha BETWEEN '01/01/2016' AND '12/31/2016'
      GROUP BY G.E, G.S, G.Tipo, G.Batch, G.ACCT, GE.Saldo, GE.E, GE.S, GE.Tipo, GE.Numero) A
WHERE (A.Saldo_Loc - A.Saldo_Ext) <> 0
Mit dieser Abfrage erkenne ich die ersten 3 Fälle, den 4. aber nicht.

Abfrage GL:

E S TIPO BATCH SUM ACCT
1 1 EA 92 -139292,8 11050505
1 1 EA 92 19212,8 13551702

Abfrage GL_Ext:

E S TIPO NUMERO SALDO ACCT
1 1 EA 92 -139292,8 11050505
1 1 EA 92 19212,8 13551702
1 1 EA 92 120080 14552501

die Zeile mit der Account-Nummer 14552501 habe ich in GL_Ext, aber nicht in GL. Laut der Dokumentation vom FULL OUTER JOIN sollte die doch aber mit eingefügt werden, oder nicht ? Dann halt mit NULL von der linken Seite

Ideen ?

nahpets 31. Okt 2017 16:28

AW: FULL OUTER JOIN zeigt nicht alle records
 
Werde jetzt mal raten, da ich noch nicht ganz durchsteige:

Du hast da zwei Selects geschachtelt.

Die bemängele Zeile fehlt bereits im inneren Select?

Oder erst im Äußeren?

Wenn Null für den nicht gefundenen Datensatz geliefert wird, wird dieser Vergleich scheitern:
SQL-Code:
where (A.Saldo_Loc - A.Saldo_Ext) <> 0


Was kommt bei FireBird bei einem Vergleich dieser Art heraus?
SQL-Code:
where (Null - 42) <> 0


Wird es so besser?
SQL-Code:
where (COALESCE(A.Saldo_Loc,0) - COALESCE(A.Saldo_Ext,0) <> 0

MyRealName 31. Okt 2017 16:39

AW: FULL OUTER JOIN zeigt nicht alle records
 
Schon beim inneren SELECT (mit dem FULL OUTER JOIN) fehlt die Zeile mit der Account Nummer.
Ich hab mal im inneren SELECT auch das SUM mit einem COALESCE erweitert, aber auch das brachte die Zeile nicht hervor.
Und dadurch, dass im inneren SELECT die Zeile schon nicht vorkommt, brauche ich am äusseren WHERE nicht basteln, oder ?

nahpets 31. Okt 2017 16:54

AW: FULL OUTER JOIN zeigt nicht alle records
 
Lass bitte das äußere Select weg, bis das Inner das richtige Ergebnis liefert.

Dashier wird (vermutlich) nicht funktionieren, sofern einer der Werte Null sein kann.
SQL-Code:
(GE.E=G.E AND GE.S=G.S AND GE.Tipo=G.Tipo AND GE.Numero=G.Batch AND GE.Acct=G.Acct)

Bin mir da aber nicht sicher und hab' keine Datenbank zur Verfügung, mit der ich das mal eben testen könnte.

MyRealName 31. Okt 2017 17:01

AW: FULL OUTER JOIN zeigt nicht alle records
 
Diese Abfrage hier geht, ist aber sehr langsam :

Code:
SELECT B.*, GE.*
FROM (
      SELECT G.E E_Loc, G.S S_Loc, G.Tipo Tipo_Loc, G.Batch Numero_Loc, CAST(COALESCE(SUM(G.Debit-G.Credit), 0) AS Currency) Saldo_Loc, G.ACCT
      FROM GL G
      WHERE G.Fecha BETWEEN '01/01/2016' AND '12/31/2016'
      GROUP BY G.E, G.S, G.Tipo, G.Batch, G.Acct
     ) B
FULL JOIN GL_EXT GE ON (GE.E=B.E_Loc AND GE.S=B.S_Loc AND GE.Tipo=B.Tipo_Loc AND GE.Numero=B.numero_Loc AND GE.Acct=B.Acct)

nahpets 31. Okt 2017 17:09

AW: FULL OUTER JOIN zeigt nicht alle records
 
Da GL und G in der inneren Abfrage nicht über irgendeine Bedingung verknüpft sind, wird das erstmal ein kartesische Produkt, das ist klar, dass das langsam wird und bei großen Datenmengen wird's garantiert irgendwann unerträglich langsam.

Und da im inneren Select nur Werte von G ausgegeben werden, frag' ich mich gerade, ob GL nicht einfach weg kann. (Ist vermutlich nur beim Kopieren des SQLs versehentlich übriggeblieben.)

MyRealName 31. Okt 2017 17:33

AW: FULL OUTER JOIN zeigt nicht alle records
 
Zitat:

Zitat von nahpets (Beitrag 1384652)
Und da im inneren Select nur Werte von G ausgegeben werden, frag' ich mich gerade, ob GL nicht einfach weg kann. (Ist vermutlich nur beim Kopieren des SQLs versehentlich übriggeblieben.)

Nee, GL hat die Werte der live-datenbank während gl_ext die werte einer vorherigen Kopie haben, die sollen ja verglichen werden um Abweichungen zu finden. GL ist eine transaktionale Accounting Tabelle, wo alle Bewegungen der Buchhaltung gespeichert werden.

Ich hab jetzt was anderes probiert : Ein Left Join um die ersten 3 Fälle abzudecken und dann ein union select zu einem Select der nur GL_Ext abfragt nach Zeilen, die nicht in GL vorkommen, um den Fall 4 abzudecken.

Code:
SELECT G.ACCT,
             G.E E_Loc, G.S S_Loc, G.Tipo Tipo_Loc, G.Batch Numero_Loc, CAST(COALESCE(SUM(G.Debit-G.Credit), 0) AS Currency) Saldo_Loc,
             GE.E E_Ext, GE.S S_Ext, GE.Tipo Tipo_Ext, GE.Numero Numero_Ext, COALESCE(GE.Saldo, 0) Saldo_Ext
      FROM GL G
      LEFT JOIN GL_EXT GE ON (GE.E=G.E AND GE.S=G.S AND GE.Tipo=G.Tipo AND GE.Numero=G.Batch AND GE.Acct=G.Acct)
      WHERE G.Fecha BETWEEN '01/01/2016' AND '12/31/2016'
      GROUP BY G.E, G.S, G.Tipo, G.Batch, G.ACCT, GE.Saldo, GE.E, GE.S, GE.Tipo, GE.Numero
HAVING CAST(COALESCE(SUM(G.Debit-G.Credit), 0) AS Currency) <> COALESCE(GE.Saldo, 0)

UNION

SELECT G.Acct,
       NULL E_Loc, NULL S_Loc, NULL Tipo_Loc, NULL Numero_Loc, NULL Saldo_Loc,
       G.E E_Ext, G.S S_Ext, G.Tipo Tipo_Ext, G.Numero Numero_Ext,
       G.Saldo Salo_Ext
FROM GL_EXT G
WHERE NOT EXISTS (SELECT G1.Conteo FROM GL G1 WHERE G1.E=G.E AND G1.S=G.S AND G1.Tipo=G.Tipo AND G1.Batch=G.Numero AND G1.ACCT=G.ACCT)

nahpets 31. Okt 2017 17:42

AW: FULL OUTER JOIN zeigt nicht alle records
 
Sehe gerade meinen Denkfehler, hatte mit hier
SQL-Code:
FROM GL G
ein Komma zwischen GL und G gedacht, aber G ist ja "nur" der Alias für GL.

War also Quatsch, was ich oben schrieb :-(

MyRealName 1. Nov 2017 13:40

AW: FULL OUTER JOIN zeigt nicht alle records
 
passiert, keine Sorge.

Die Frage bleibt aber bestehen, auch wenn ich eine Lösung gefunden habe, die zwar kein FULL OUTER JOIN nutzt und schnell ist : Sollte es denn nicht funktionieren ? Laut der Firebird Dokumentation schon, oder ?

Olli73 1. Nov 2017 14:19

AW: FULL OUTER JOIN zeigt nicht alle records
 
Zitat:

Zitat von MyRealName (Beitrag 1384694)
Die Frage bleibt aber bestehen, auch wenn ich eine Lösung gefunden habe, die zwar kein FULL OUTER JOIN nutzt und schnell ist : Sollte es denn nicht funktionieren ? Laut der Firebird Dokumentation schon, oder ?

Funktioniert es, wenn du
Code:
WHERE G.Fecha BETWEEN '01/01/2016' AND '12/31/2016'
durch
Code:
WHERE G.Fecha BETWEEN '01/01/2016' AND '12/31/2016' or G.Fecha is null
ersetzt?


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:04 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz