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

[SQL-Abfrage] Welcher JOIN führt zum Ziel?

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von funkyice, 11 August 2016.

  1. funkyice

    funkyice Benutzer

    Hallo zusammen,

    ich komme mit einer Datenbankabfrage nicht so recht weiter und auch die Suche brachte keine entscheidenden Ergebnisse leider.

    die Ausgangslage ist:
    - Tabelle Kunden
    - Tabelle Rechnungen
    - Tabelle Gutschriften

    Das Ergebnis soll recht simpel sein mit folgender Struktur
    Kundennr | Kundenname | Kundengr | Umsatz Vorjahr | Umsatz lft. Jahr | Differenz

    Ich bin aktuell so vorgegangen, dass ich mir zunächst mittels "WITH" die Daten hole/filtere für "Umsatzvorjahr" und "Umsatzlftjahr", hier nur mal exemplarisch für das Umsatzvorjahr:
    Code:
    WITH umsatzvorjahr as (
    
    SELECT
       g.Kundennr AS Kundennr,
       g.Kundengr AS Kundengr,
       SUM(g.GU_Summe_MW)  AS Umsatz
       
    FROM
       [Gutschriften] as g
    
    GROUP BY
       g.Kundennr, g.Kundengr, g.Buchungsdatum
    
    HAVING  /*Filtert Beginn des Vorjahres bis zum Stichtag des aktuellen Jahres*/
       (g.Buchungsdatum <= (CONVERT (varchar(10),(DATEPART(DAY,@Datum_bis)),104) + '.' + CONVERT (varchar(10),(DATEPART(MONTH,@Datum_bis)),104) + '.' + CONVERT (varchar(10),(DATEPART(YEAR,@Datum_bis)-1),104)) AND
       DATEPART(MONTH,g.Buchungsdatum) >= '1' AND
       DATEPART(YEAR,g.Buchungsdatum) LIKE DATEPART(YEAR,@Datum_bis)-1)
    
    UNION
    
    SELECT
       r.Kundennr AS Kundennr,
       r.Kundengr AS Kundengr,
       SUM(r.RE_Summe_MW) AS Umsatz
       
    FROM
       [Rechnungen] as r
    
    GROUP BY
       r.Kundennr, r.Kundengr, r.Buchungsdatum
    
    HAVING  /*Filtert Beginn des Vorjahres bis zum Stichtag des aktuellen Jahres*/
       (r.Buchungsdatum <= (CONVERT (varchar(10),(DATEPART(DAY,@Datum_bis)),104) + '.' + CONVERT (varchar(10),(DATEPART(MONTH,@Datum_bis)),104) + '.' + CONVERT (varchar(10),(DATEPART(YEAR,@Datum_bis)-1),104)) AND
       DATEPART(MONTH,r.Buchungsdatum) >= '1' AND
       DATEPART(YEAR,r.Buchungsdatum) LIKE DATEPART(YEAR,@Datum_bis)-1)
    

    Mein Select später sieht aktuell wie folgt aus:
    Code:
    SELECT
       customer.No_ AS Kundennr,
       customer.Name AS Kundenname,
       customer.[Customer Group] AS Kundengruppe,
    
       ISNULL(SUM(umsatzvorjahr.Umsatz),0) AS 'Umsatz Vorjahr',
       ISNULL(SUM(umsatzlfdjahr.Umsatz),0) AS Umsatz,
       ISNULL(SUM(umsatzlfdjahr.Umsatz),0) - ISNULL(SUM(umsatzvorjahr.Umsatz),0) AS Differenz
       
    
    FROM
       [Kunden] customer  LEFT JOIN
       umsatzvorjahr ON umsatzvorjahr .Kundennr = customer.No_ LEFT JOIN
       umsatzlfdjahr  ON umsatzlfdjahr.Kundennr = customer.No_
    
    GROUP BY
       customer.No_, customer.Name, customer.[Customer Group]
    
    Das Ergebnis für die "Umsätze" ist immer falsch. Habe ich einen Denkfehler? Schaue ich mir die Ergebnisse aus den Anfragen für "umsatzvorjahr" und "umsatzlfdjahr" an, ist alles noch korrekt.

    Freue mich über Eure Ratschläge.

    Danke
    Sebastian
     
  2. ukulele

    ukulele Datenbank-Guru

    Nun du gruppierst deine Daten mehrfach nach Kunden, einmal vor dem UNION ALL im WITH-Teil und dann außerhalb nochmal. Das ist nicht schlimm aber ich würde versuchen es einfacher zu halten. Wenn die beiden Zahlen für Rechnungen und Gutschriften korrekt sind und deine Kunden-Tabelle pro Kundennr nur einen Eintrag hat sollte auch das Endergebnis richtig sein.

    PS: Du gruppierst auch noch nach Buchungsdatum, ist das sinnvoll?
     
  3. ukulele

    ukulele Datenbank-Guru

    Hier mal etwas umgestellt:
    Code:
    WITH umsatz(Kundennr,Kundengr,Buchungsdatum,Umsatz) AS (
    SELECT   g.Kundennr,
         g.Kundengr,
         g.Buchungsdatum,
         g.GU_Summe_MW
    FROM   [Gutschriften] AS g
    WHERE   g.Buchungsdatum BETWEEN dateadd(year,datediff(year,0,@Stichtag),0) AND @Stichtag
    OR     g.Buchungsdatum BETWEEN dateadd(year,datediff(year,0,@Stichtag)-1,0) AND dateadd(year,-1,@Stichtag)
    UNION ALL
    SELECT   r.Kundennr,
         r.Kundengr,
         r.Buchungsdatum,
         r.RE_Summe_MW
    FROM   [Rechnungen] AS r
    WHERE   r.Buchungsdatum BETWEEN dateadd(year,datediff(year,0,@Stichtag),0) AND @Stichtag
    OR     r.Buchungsdatum BETWEEN dateadd(year,datediff(year,0,@Stichtag)-1,0) AND dateadd(year,-1,@Stichtag)
         )
    SELECT   k.No_ AS Kundennr,
         k.Name AS Kundenname,
         k.[Customer Group] AS Kundengruppe,
         isnull(sum(u1.Umsatz),0) AS Umsatz,
         isnull(sum(u2.Umsatz),0) AS [Umsatz Vorjahr],
         isnull(sum(u1.Umsatz),0) -
         isnull(sum(u2.Umsatz),0) AS Differenz
    FROM   [Kunden] k
    LEFT JOIN umsatz u1
    ON     k.No_ = u1.Kundennr
    AND     datepart(yyyy,u1.Buchungsdatum) = datepart(yyyy,@Stichtag)
    LEFT JOIN umsatz u2
    ON     k.No_ = u2.Kundennr
    AND     datepart(yyyy,u2.Buchungsdatum) = datepart(yyyy,@Stichtag)-1
    GROUP BY k.No_,k.Name,k.[Customer Group]
     
  4. drdimitri

    drdimitri Datenbank-Guru

    Die Verwendung
    Kann's sein, dass da die Klammerung zwischen den OR Blöcken fehlt?
     
  5. ukulele

    ukulele Datenbank-Guru

    Hm nö im WHERE-Teil schränke ich nur das Buchungsdatum auf Jahr des Stichtags bis Stichtag oder Vorjahr des Stichtags bis Stichtag - 1 Jahr ein. BETWEEN A AND B ist dabei eine Bedingung Wahr/Falsch und OR verknüpft sie mit der Anderen.

    Das könnte man auch außerhalb des WITH machen, funkyice wollte aber im ersten Schritt nur auf relevante Datensätze Filtern.
     
Die Seite wird geladen...
Ähnliche Themen - [SQL Abfrage] Welcher
  1. hstfs23
    Antworten:
    5
    Aufrufe:
    3.383

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