Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi SQL: FULL OUTER JOIN mit sich selbst (https://www.delphipraxis.net/130306-sql-full-outer-join-mit-sich-selbst.html)

GroHae 6. Mär 2009 08:31

Datenbank: MSSQL 2000 • Zugriff über: ODBC

SQL: FULL OUTER JOIN mit sich selbst
 
Hallo zusammen,

ich will eine Auswertung auf eine Tabelle machen.
Umsatz pro Debitor
Dabei sollen die Daten aus dem Jahr 2009 mit dem Jahr 2008 verglichen werden.
Wenn Debitoren in dem einen Jahr nicht sind sollen sie trotzdem nicht unterschlagen werden.

Das Ergebnis soll also so aussehen:

  • Debitor --- Umsatz_2008 ---- Umsatz_2009
    A --------- NULL --------- 1000
    B --------- 2500 --------- 2500
    C --------- 1500 --------- NULL
    D --------- 2000 --------- 140

SQL-Code:
  SELECT SUM(AktuellesJahr.Umsatz) AS Summe_Umsatz,
  SUM(Vorjahr.Umsatz) AS Summe_Umsatz_Vorjahr,
  AktuellesJahr.Debitor_ID
FROM dbo.DBRechnung Vorjahr FULL OUTER JOIN dbo.DBRechnung AktuellesJahr ON
      Vorjahr.UnternehmenNr_ID = AktuellesJahr.UnternehmenNr_ID AND
      Vorjahr.Monat_ID = AktuellesJahr.Monat_ID AND
      Vorjahr.Debitor_ID = AktuellesJahr.Debitor_ID AND
      Vorjahr.Artikel_ID = AktuellesJahr.Artikel_ID
WHERE
  (AktuellesJahr.Jahr_ID = 2009) AND (AktuellesJahr.Monat_ID = 1) AND (AktuellesJahr.UnternehmenNr_ID = 3) AND
  (Vorjahr.Jahr_ID = 2008) AND (Vorjahr.Monat_ID = 1) AND (Vorjahr.UnternehmenNr_ID = 3)
GROUP BY AktuellesJahr.Debitor_ID
Es klappt aber nicht:
a) ich bekomme nur die einen Teil der Daten (nur die welche in beiden Jahren sind)
b) Die Summen sind falsch

Etwa so:

  • Debitor --- Umsatz_2008 ---- Umsatz_2009
    B --------- 150 --------- 300
    D --------- 981 --------- 25

Ich komme einfach nicht drauf was ich falsch mache :pale:

NormanNG 6. Mär 2009 09:31

Re: SQL: FULL OUTER JOIN mit sich selbst
 
Hi,

auf den ersten schnellen Blick fällt auf:

SQL-Code:
where ... AND (Vorjahr.Monat_ID = 1) AND (Vorjahr.UnternehmenNr_ID = 3)
damit selektierst du bestimmte Zeilen aus der Vorjahr-Datenmenge und verhinderst, das
NULL-Werte aus Vorjahr eingeschlossen werden...

GroHae 6. Mär 2009 10:18

Re: SQL: FULL OUTER JOIN mit sich selbst
 
Hi,

Zitat:

damit selektierst du bestimmte Zeilen aus der Vorjahr-Datenmenge und verhinderst, das
NULL-Werte aus Vorjahr eingeschlossen werden...
Das verstehe ich nicht. :oops:

Ich will ja zwei verschiedene Datenbereiche zusammen fügen. Daten aus 01/2009 mit Daten aus 01/2008.


Ups Fehler in meinem original Posting:
Debitor --- Umsatz_2009 ---- Umsatz_2009
Debitor --- Umsatz_2008 ---- Umsatz_2009
Hab's geändert



Davon abgesehen: auch wenn ich sage
SQL-Code:
WHERE    (AktuellesJahr.Jahr_ID = 2009) AND (AktuellesJahr.Monat_ID = 1) AND (AktuellesJahr.UnternehmenNr_ID = 3) AND
(Vorjahr.Jahr_ID = 2008)
bekomme ich die selben Daten.
Übrigens egal ob ich JOIN, FULL OUTER JOIN, LEFT JOIN oder RIGHT JOIN sage. der Datenbestand für die zwei Zeiträume ist aber definitiv unterschiedlich


Das kann nur eins bedeuten:
Ich hab da irgendwo ein grundsätzliches Verständnisproblem

DeddyH 6. Mär 2009 10:27

Re: SQL: FULL OUTER JOIN mit sich selbst
 
Ich bin jetzt auch ein bisschen kirre, aber was kommt hierbei heraus?
SQL-Code:
SELECT
  SUM(CASE A.Umsatz WHEN NULL THEN 0 ELSE A.Umsatz) AS Summe_Umsatz,
  SUM(CASE V.Umsatz WHEN NULL THEN 0 ELSE V.Umsatz) AS Summe_Umsatz_Vorjahr,
  A.Debitor_ID
FROM
  dbo.DBRechnung V
FULL OUTER JOIN
  dbo.DBRechnung A ON
      V.UnternehmenNr_ID = A.UnternehmenNr_ID AND
      V.Monat_ID = A.Monat_ID AND
      V.Debitor_ID = A.Debitor_ID AND
      V.Artikel_ID = A.Artikel_ID
WHERE
  A.Jahr_ID = 2009 
  AND A.Monat_ID = 1
  AND A.UnternehmenNr_ID = 3
GROUP BY
  A.Debitor_ID

mquadrat 6. Mär 2009 10:32

Re: SQL: FULL OUTER JOIN mit sich selbst
 
Wenn unbekannt ist, ob bzw. in welchem Jahr gar keine Daten drin sind, braucht man dann nicht noch die Debitor-Tabelle? (Möglicherweise erledigt das der full outer join, aber damit hab ich noch nie gearbeitet).

Also so irgendwie:
SQL-Code:
select
  * 
from
  debitor
  left outer join umsatz_vorjahr on ...
  left outer join umsatz_aktuelles Jahr on ...
where
  ...

TBx 6. Mär 2009 10:58

Re: SQL: FULL OUTER JOIN mit sich selbst
 
Du brauchst im Grunde 3 Datenmengen, die Du zusammenjoinen mußt:
  • alle Debitoren, die in mindestens einem der beiden Jahre Umsatz gemacht haben (a)
  • Umsätze der Debitoren im aktuellen Jahr (b)
  • Umsätze der Debitoren im Vorjahr (c)

Diese Daten kannst Du alle aus dbo.DBRechnung gewinnen.
Beispiel:
SQL-Code:
SELECT a.DEBITOR_ID,
       sum (b.Umsatz) AktUmsatz,
       sum (c.Umsatz) OldUmsatz
  FROM dbo.DBRechnung a
    LEFT JOIN dbo.DBRechnung b on ((b.DEBITOR_ID=a.DEBITOR_ID) AND (b.JAHR_ID = :AktJahr))
    LEFT JOIN dbo.DBRechnung c on ((c.DEBITOR_ID=a.DEBITOR_ID) AND (c.JAHR_ID = :AktJahr - 1))
  WHERE a.JAHR_ID in (:AktJahr, :AktJahr - 1)
  GROUP BY a.DEBITOR_ID
Ich habe da die Artikel und den Monat rausgelassen. wenn Du das Ganze auch noch artikelweise und/oder monatsweise auswerfen willst, muss entsprechend ergänzt werden.

Gruß
Thomas

PS: Trocken runtergeschrieben, ungetestet

GroHae 6. Mär 2009 11:23

Re: SQL: FULL OUTER JOIN mit sich selbst
 
Hi All,

@DeddyH

Ich habe es mit
SQL-Code:
SELECT
  SUM(ISNULL(A.Umsatz,0)) AS Summe_Umsatz,
  SUM(ISNULL(V.Umsatz,0)) AS Summe_Umsatz_Vorjahr,
  A.Debitor_ID
FROM
  dbo.DBRechnung V
FULL OUTER JOIN
  dbo.DBRechnung A ON
      V.UnternehmenNr_ID = A.UnternehmenNr_ID AND
      V.Monat_ID = A.Monat_ID AND
      V.Debitor_ID = A.Debitor_ID AND
      V.Artikel_ID = A.Artikel_ID
WHERE
  A.Jahr_ID = 2009
  AND V.Jahr_ID = 2008
  AND A.Monat_ID = 1
  AND A.UnternehmenNr_ID = 3
GROUP BY
  A.Debitor_ID
probiert, was mir aber die selben(falschen) Ergebisse bringt.


@mquadrat und TBx

hm.. über die Stammtabellen (Debitorenen, Artikel) gehen, ja das wäre eine Möglichkeit.
daran habe ich nicht gedacht. Ich versehe zwar immer noch nicht was bei dem anderen Ansatz falsch ist, aber einen View (oder so) Debitoren mit ihren Artikeln und ihren Umsätzen sollte das Problem lösen

Danke!

:dp:

TBx 6. Mär 2009 11:33

Re: SQL: FULL OUTER JOIN mit sich selbst
 
Zitat:

Zitat von GroHae
Ich versehe zwar immer noch nicht was bei dem anderen Ansatz falsch ist

Du kannst schon deshalb nur Daten für Debitoren bekommen, weil Du in Deiner Joinbedingung einschränkst, dass die Daten in beiden Jahren zum Selben Artikel und in den selben Monat gehören müssen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:53 Uhr.

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