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

Quartalsumsatz

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von Hoppel, 4 September 2015.

  1. Hoppel

    Hoppel Aktiver Benutzer

    Hallo,

    ich möchte für einen Jahreszeitraum den Umsatz für jedes Quartal anzeigen lassen.

    Code:
    select distinct b.Artikelnummer, Q1.AbsatzQ1, Q1.UmsatzQ1, Q2.AbsatzQ2, Q2.UmsatzQ2, Q3.AbsatzQ3, Q3.UmsatzQ3, Q4.AbsatzQ4, UmsatzQ4
    from Bestellungen b,
    (select Artikelnummer, SUM(Menge) as AbsatzQ1, ROUND(SUM(Einzelpreis*Menge),2) as UmsatzQ1
    from Bestellungen
    where convert(date, Datum) >= '01.01.2012' and convert(date, Datum) <'01.04.2012'
    group by Artikelnummer) as Q1,
    
    (select Artikelnummer, SUM(Menge) as AbsatzQ2, ROUND(SUM(Einzelpreis*Menge),2)  as UmsatzQ2
    from Bestellungen
    where  convert(date, Datum) >= '01.04.2012' and convert(date, Datum) <'01.07.2012'
    group by Artikelnummer) as Q2,
    
    (select Artikelnummer, SUM(Menge) as AbsatzQ3, ROUND(SUM(Einzelpreis*Menge),2)  as UmsatzQ3
    from Bestellungen
    where convert(date, Datum) >= '01.08.2012' and convert(date, Datum) <'01.10.2012'
    group by Artikelnummer) as Q3,
    
    (select Artikelnummer, SUM(Menge) as AbsatzQ4, ROUND(SUM(Einzelpreis*Menge),2)  as UmsatzQ4
    from Bestellungen
    where convert(date, Datum) >= '01.10.2012' and convert(date, Datum) <'01.01.2013'
    group by Artikelnummer) as Q4
    
    where b.Artikelnummer = Q1.Artikelnummer and Q1.Artikelnummer = Q2.Artikelnummer and Q2.Artikelnummer = Q3.Artikelnummer and Q3.Artikelnummer = Q4.Artikelnummer
    order by b.Artikelnummer
    
    Jetzt habe ich aber die Befürchtung, dass nur die Artikel angezeigt werden die in allen vier Quartalen abgesetzt wurden.

    Habt ihr eine Idee wie ich diesen Fehler umgehe?

    Vielen Dank!
     
  2. ukulele

    ukulele Datenbank-Guru

    Du arbeitest zwar mit Joins, diese werden aber nicht explizit als solche ausgewiesen. Es handelt sich um INNER JOINs, für dein Vorhaben brauchst du LEFT JOINs, das würde dein Problem zunächst lösen.

    Du hast aber ein ziemlich wildes Query das dir zumindest inhaltliche Fehler liefern wird, du müsstest z.B. erst die Preise runden und dann summieren sonst wirst du Abweichungen haben. Auch bietet dir SQL viele Möglichkeiten es einfacher und vermutlich schneller zu machen, probier mal das hier:
    Code:
    SELECT    b.Artikelnummer,
            sum( CASE WHEN datepart(q,convert(date,Datum)) = 1 THEN Menge ELSE 0 END ) AS AbsatzQ1,
            sum( CASE WHEN datepart(q,convert(date,Datum)) = 1 THEN round(Einzelpreis*Menge,2) ELSE 0 END ) AS UmsatzQ1,
            sum( CASE WHEN datepart(q,convert(date,Datum)) = 2 THEN Menge ELSE 0 END ) AS AbsatzQ2,
            sum( CASE WHEN datepart(q,convert(date,Datum)) = 2 THEN round(Einzelpreis*Menge,2) ELSE 0 END ) AS UmsatzQ2,
            sum( CASE WHEN datepart(q,convert(date,Datum)) = 3 THEN Menge ELSE 0 END ) AS AbsatzQ3,
            sum( CASE WHEN datepart(q,convert(date,Datum)) = 3 THEN round(Einzelpreis*Menge,2) ELSE 0 END ) AS UmsatzQ3,
            sum( CASE WHEN datepart(q,convert(date,Datum)) = 4 THEN Menge ELSE 0 END ) AS AbsatzQ4,
            sum( CASE WHEN datepart(q,convert(date,Datum)) = 4 THEN round(Einzelpreis*Menge,2) ELSE 0 END ) AS UmsatzQ4
    FROM    Bestellungen b
    WHERE    datepart(year,convert(date,Datum)) = 2012
    GROUP BY b.Artikelnummer
    ORDER BY b.Artikelnummer
    Wenn deine Spalte Datum schon ein Datumsformat hat kannst du dir das convert() auch sparen.
     
    Hoppel gefällt das.
  3. Hoppel

    Hoppel Aktiver Benutzer

    Wow!

    Grandiose Lösung. Ich habe viel zu kompliziert gedacht. Vielen vielen Dank!!
     
  4. Hoppel

    Hoppel Aktiver Benutzer

    Ich habe diesbezüglich noch eine weitere Frage. Ich möchte jetzt noch die Anzahl der Kunden hinzufügen und habe folgendes ergänzt:

    Code:
    SELECT    b.Artikelnummer,
            sum( CASE WHEN datepart(YYYY,convert(date,Datum)) = 2012 THEN Menge ELSE 0 END ) AS Absatz12,
            count( CASE WHEN datepart(YYYY,convert(date,Datum)) = 2012 Then b.Adressnummer ELSE '0' END) as AnzahlKunde12,
            sum( CASE WHEN datepart(YYYY,convert(date,Datum)) = 2013 THEN Menge ELSE 0 END ) AS Absatz13,
            count( CASE WHEN datepart(YYYY,convert(date,Datum)) = 2013 Then b.Adressnummer ELSE '0' END) as AnzahlKunde13,
            sum( CASE WHEN datepart(YYYY,convert(date,Datum)) = 2014 THEN Menge ELSE 0 END ) AS Absatz14,
            count( CASE WHEN datepart(YYYY,convert(date,Datum)) = 2014 Then b.Adressnummer ELSE '0' END) as AnzahlKunde14,
            sum( CASE WHEN datepart(YYYY,convert(date,Datum)) = 2015 THEN Menge ELSE 0 END ) AS Absatz15,
            count( CASE WHEN datepart(YYYY,convert(date,Datum)) = 2015 Then b.Adressnummer ELSE '0' END) as AnzahlKunde15
    FROM    Bestellungen b
    WHERE    datepart(year,convert(date,Datum)) >= 2012 and b.artikelnummer like 'Test%'
    GROUP BY b.Artikelnummer
    ORDER BY b.Artikelnummer
    Jetzt wird aber für die Anzahl der Kunden 2013, 2014 und 2015 die gleiche Anzahl wie 2012 ausgegeben. Wo liegt der Fehler?
     
  5. ukulele

    ukulele Datenbank-Guru

    count() zählt NULL, 0, 1, oder 524 immer als eine Zeile. Du müsstest also eher mit sum(CASE WHEN Datum = True THEN 1 ELSE 0 END) arbeiten.
     
  6. Hoppel

    Hoppel Aktiver Benutzer

    Vielen dank! Dann habe ich jetzt noch das Problem, dass er einen Kunden der in dem Zeitraum zwei Bestellungen gemacht doppelt zählt. Kriege ich ein "distinct" irgendwie eingebaut?
     
  7. ukulele

    ukulele Datenbank-Guru

    Hm das ist etwas knifflig. Du könntest eventuell mit count(CASE WHEN Datum = True THEN kundennr ELSE NULL END) -1 rechnen. Da NULL als ein Wert mit gezählt wird musst du eins abziehen. Wenn dann aber alle Bestellungen vom selben Kunden sind geht der Zähler fälschlicherweise auf 0, ist also in einem Ausnahmefall unscharf.
     
  8. akretschmer

    akretschmer Datenbank-Guru

    Dann solltest Du den Kunden mit als Spalte im Resultat führen und danach auch mit gruppieren.
     
  9. Hoppel

    Hoppel Aktiver Benutzer

    Mir ist die Tage noch eine weitere Frage in den Sinn gekommen:

    Für ein noch nicht beendet das Jahr (z.B. 2015) ist die Aussage der abgesetzten Menge teilweise nicht aussagekräftig. Ist es möglich, dass wenn z.B. im Jahr 2015 zwei Monate fehlen, die Absatzmenge aus dem Monat des vergangenen Jahres nimmt?

    Also das in der Summe für das Jahr 2015 die Monate 11 und 12 aus dem Jahr 2014 als Hochrechnung in die Summe miteinbezogen wird?

    Code:
    SELECT    b.Artikelnummer,
            sum( CASE WHEN datepart(YYYY,convert(date,Datum)) = 2012 THEN Menge ELSE 0 END ) AS Absatz12,
            sum( CASE WHEN datepart(YYYY,convert(date,Datum)) = 2013 THEN Menge ELSE 0 END ) AS Absatz13,
            sum( CASE WHEN datepart(YYYY,convert(date,Datum)) = 2014 THEN Menge ELSE 0 END ) AS Absatz14,
            sum( CASE WHEN datepart(YYYY,convert(date,Datum)) = 2015 THEN Menge ELSE 0 END ) AS Absatz15
    FROM    Bestellungen b
    WHERE    datepart(year,convert(date,Datum)) >= 2012 and b.artikelnummer like 'Test%'
    GROUP BY b.Artikelnummer
    ORDER BY b.Artikelnummer
     
  10. akretschmer

    akretschmer Datenbank-Guru

    Sicher. Die Frage ist eher, ob man das auch so will.
     
  11. ukulele

    ukulele Datenbank-Guru

    Code:
    SELECT    b.Artikelnummer,
            sum( CASE WHEN datepart(YYYY,convert(date,Datum)) = 2012 THEN Menge ELSE 0 END ) AS Absatz12,
            sum( CASE WHEN datepart(YYYY,convert(date,Datum)) = 2013 THEN Menge ELSE 0 END ) AS Absatz13,
            sum( CASE WHEN datepart(YYYY,convert(date,Datum)) = 2014 THEN Menge ELSE 0 END ) AS Absatz14,
            sum( CASE WHEN datepart(YYYY,convert(date,Datum)) = 2015 THEN Menge ELSE 0 END ) AS Absatz15,
            sum( CASE
            WHEN    datepart(YYYY,convert(date,Datum)) = 2014
            AND        convert(date,Datum) > dateadd(year,-1,getdate())
            OR        datepart(YYYY,convert(date,Datum)) = 2015
            AND        convert(date,Datum) <= getdate()
            THEN    Menge
            ELSE    0
            END ) AS Absatz15_Hochrechnung
    FROM    Bestellungen b
    WHERE    datepart(year,convert(date,Datum)) >= 2012 and b.artikelnummer like 'Test%'
    GROUP BY b.Artikelnummer
    ORDER BY b.Artikelnummer
     
  12. Hoppel

    Hoppel Aktiver Benutzer

    Vielen Dank! Genau so etwas habe ich gesucht.

    Kannst Du mir noch kurz erklären, wie die Abfrage aufgebaut ist?
     
  13. ukulele

    ukulele Datenbank-Guru

    Da gibts nicht viel zu erläutern, eine weitere Spalte wie bisher nur das CASE WHEN mit mehreren Bedingungen. Entweder Jahr = 2014 aber Datum größer Heute - 1 Jahr oder Jahr = 2015 und Datum <= Heute (was eigentlich immer gegeben sein sollte).
     

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