Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Kompliziertes Update Statement (https://www.delphipraxis.net/168322-kompliziertes-update-statement.html)

mika 15. Mai 2012 11:02

Datenbank: ADS • Version: 9 • Zugriff über: ADS Komponenten, SQL

Kompliziertes Update Statement
 
Hallo Forum,

ich hoffe dass ihr mir eventuell etwas auf die Sprünge helfen könnt. Kurz zu meinem Problem, ich muss eine Lagerumsatzgeschwindigkeit berechnen. Soweit nicht so wild. Meine Tabelle enthält allerdings pro Geschäftsjahr ca 70k Datensätze, weswegen ich nicht jeden einzeln bearbeiten möchte. Das würde Stunden dauern. Die Formel ist recht einfach und ich hab gehofft das ganze in einem SQL unterbringen zu können.

Meine Tabelle sieht im groben so aus
Code:
Jahr: Integer
Monat: Integer
Kunde: Integer
Artikel: Integer
Col: String
AbverkauftMenge: CurDouble
IstBestand: CurDouble
LUG: CurDouble
Die LUG soll so berechnet werden:

LUG = (Summe(AbverkauftMenge) der letzten 12 Monate) / (Summe(IstBestand) der letzten 13 Monate) * 13

Jetzt habe ich gehofft dass ich mit einem Statement der folgenden Art das ganze einfach dem DB-Server überlassen könnte:
Code:
UPDATE
  Statistik
SET
  LUG =
  ( 
    SELECT
      SUM(AbverkauftMenge) AS Menge
    FROM
      Statistik
    WHERE
     Kunde = Statistik.Kunde
     AND Artikel = Statistik.Artikel
     AND Col = Statistik.Col
      AND ((Jahr >= Statistik.Jahr-1 AND Monat >= Statistik.Monat+1)
     OR (Jahr <= Statistik.Jahr AND Monat <= Statistik.Monat))
  )
  / 
  ( 
    SELECT
      SUM(IstBestand) AS Menge
    FROM
      Statistik
    WHERE
     Kunde = Statistik.Kunde
     AND Artikel = Statistik.Artikel
     AND Col = Statistik.Col
      AND ((Jahr >= Statistik.Jahr-1 AND Monat >= Statistik.Monat)
     OR (Jahr <= Statistik.Jahr AND Monat <= Statistik.Monat))
  )
  * 13
Jedoch kommen bei diesem Statement für alle Datensätze der gleiche Wert in jeder Zelle raus. Ich denke das die Kunde/Artikel/Col Where-Klausel nur ein einziger Wert genommen wird...

Vielleicht ist hier ja n DB Profi der mir da n bisschen auf die Sprünge helfen kann, Danke schonmal im voraus!

Lg, Mika

// Edit: Gelöst: Danke für eure Hilfe !

Neutral General 15. Mai 2012 11:12

AW: Kompliziertes Update Statement
 
Hallo,

Du solltest/musst entweder den Statistik-Tabellen in den Sub-Selects oder der Statistik-Tabelle im Update einen Alias geben. Sonst macht der da nur Unsinn!

SQL-Code:
UPDATE
  Statistik
SET
  LUG =
  ( 
    SELECT
      SUM(AbverkauftMenge) AS Menge
    FROM
      Statistik as st1
    WHERE
     st1.Kunde = Statistik.Kunde
     AND st1-Artikel = Statistik.Artikel
     AND st1.Col = Statistik.Col
      AND ((st1.Jahr >= Statistik.Jahr-1 AND st1.Monat >= Statistik.Monat+1)
     OR (st1.Jahr <= Statistik.Jahr AND st1.Monat <= Statistik.Monat))
  )
  / 
  ( 
    SELECT
      SUM(IstBestand) AS Menge
    FROM
      Statistik as st2
    WHERE
     st2.Kunde = Statistik.Kunde
     AND st2.Artikel = Statistik.Artikel
     AND st2.Col = Statistik.Col
      AND ((st2.Jahr >= Statistik.Jahr-1 AND st2.Monat >= Statistik.Monat)
     OR (st2.Jahr <= Statistik.Jahr AND st2.Monat <= Statistik.Monat))
  )
  * 13

mika 15. Mai 2012 11:13

AW: Kompliziertes Update Statement
 
okai, danke für den tipp, ich probier das mal schnell aus...

mika 15. Mai 2012 11:16

AW: Kompliziertes Update Statement
 
Okai, scheint was anderes zu machen, jetzt kommt aber mein zweites Problem (was ich auch schon befürchtet habe):

Wenn keine Daten für den 2ten Subselect vohanden sind bekomme ich eine Division by Zero Fehlermeldung :-(

Neutral General 15. Mai 2012 11:21

AW: Kompliziertes Update Statement
 
dann mach ein coalesce (falls in ADO vorhanden) oder eben ein iif vor das 2. Select und reagier entsprechend darauf.

Oder sowas:

iif(2. Select is null, 0, 1. Select / 2. Select * 13)

Auch wenns ziemlich unübersichtlich wird :mrgreen:

Sir Rufo 15. Mai 2012 11:23

AW: Kompliziertes Update Statement
 
Die Abfrage des Datums-Bereichs funktioniert so aber nicht:
SQL-Code:
((st1.Jahr >= Statistik.Jahr-1 AND st1.Monat >= Statistik.Monat+1)
Nehmen wir mal an
Code:
Statistik.Jahr = 2009
Statistik.Monat = 3
dann werden folgende Daten genommen
Code:
2008 4-12
2009 4-12
2010 4-12
2011 4-12
2012 4-12
* weiter geht es gottlob nicht, denn dann geht ja die Welt unter :o) *
und jetzt noch die Verschlimmbesserung mit
SQL-Code:
OR (st1.Jahr <= Statistik.Jahr AND st1.Monat <= Statistik.Monat)
dann kommt noch hinzu
Code:
anno tuck 1-3
...
2003 1-3
2004 1-3
2005 1-3
2006 1-3
2007 1-3
2008 1-3

omata 15. Mai 2012 11:25

AW: Kompliziertes Update Statement
 
Vielleicht noch etwas kürzer...
SQL-Code:
UPDATE
  Statistik
SET
  LUG =
  ( 
    SELECT
      SUM(AbverkauftMenge) / SUM(IstBestand) * 13
    FROM
      Statistik x
    WHERE Kunde = Statistik.Kunde
      AND Artikel = Statistik.Artikel
      AND Col = Statistik.Col
      AND (   (Jahr >= Statistik.Jahr-1 AND Monat >= Statistik.Monat+1)
           OR (Jahr <= Statistik.Jahr  AND Monat <= Statistik.Monat))
  )

mika 15. Mai 2012 11:26

AW: Kompliziertes Update Statement
 
@SirRufo
Ja, ich denke das OR ist da falsch am Platz. Allerdings sollte es, wenn ich es durch ein AND ersetze, deie richtigen Daten filtern

@General
Ich probier das mal aus, ob es unübersichtilich wird ist nicht sooo wichtig :) Hauptsache es funktioniert

//edit
@omata
das wird glaub ich leider nicht gehen, da die abverkaufte menge der letzten 12 monate, und der istbestand der letzten 13 monate genommen werden soll

omata 15. Mai 2012 13:05

AW: Kompliziertes Update Statement
 
Zitat:

Zitat von mika (Beitrag 1166634)
@omata
das wird glaub ich leider nicht gehen, da die abverkaufte menge der letzten 12 monate, und der istbestand der letzten 13 monate genommen werden soll

Oh, das +1 hatte ich nicht gesehen.

Ok, dann vielleicht so...
SQL-Code:
UPDATE
  Statistik
SET
  LUG =
  (
    SELECT
      SUM(CASE WHEN Monat >= Statistik.Monat+1 
            THEN AbverkauftMenge
            ELSE 0 
          END) / SUM(IstBestand) * 13
    FROM
      Statistik x
    WHERE Kunde = Statistik.Kunde
      AND Artikel = Statistik.Artikel
      AND Col = Statistik.Col
      AND Jahr >= Statistik.Jahr-1 AND Monat >= Statistik.Monat+1
      AND Jahr <= Statistik.Jahr  AND Monat <= Statistik.Monat
  )

mika 16. Mai 2012 09:12

AW: Kompliziertes Update Statement
 
So, ich hab das jetzt erstmal so gelöst:

Code:
UPDATE
  Statistik
SET
  LUG =
  (
    SELECT
      SUM(AbverkauftMenge) AS Menge
    FROM
      Statistik a
    WHERE
     a.Kunde = Statistik.Kunde
     AND a.Artikel = Statistik.Artikel
     --AND a.Col = Statistik.Col
      AND ((a.Jahr >= Statistik.Jahr-1 AND a.Monat >= Statistik.Monat+1)
     AND (a.Jahr <= Statistik.Jahr AND a.Monat <= Statistik.Monat))
  )
  / 
  ( 
    SELECT
      IFNULL(SUM(IstBestand),1000000) AS Menge
    FROM
      Statistik b
    WHERE
     b.Kunde = Statistik.Kunde
     AND b.Artikel = Statistik.Artikel
     --AND b.Col = Statistik.Col
      AND ((b.Jahr >= Statistik.Jahr-1 AND b.Monat >= Statistik.Monat)
     AND (b.Jahr <= Statistik.Jahr AND b.Monat <= Statistik.Monat))
  )
  * 13 
WHERE Jahr = 2010
ist noch lange nicht dass was ich wollte, aber es scheint schon der richtige Weg zu sein. Ich werde da sicher noch weiter dran arbeiten (@omata, deinen vorschlag ausprobieren zB) aber da meine EIngangsfragen gelöst sind, bedanke ich mich bei euch für eure Hilfe und markiere dieses Thema als gelöst.

Klasse Forum! Wie immer ^^


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:17 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