datadexx
Goto Top

MYSQL Abfrage bereitet mir Probleme

Hallo Leute,

ich habe wieder ein Problem mit einer SQL Abfrage.

Ich habe eine Tabelle die nennt sich pbooking, darin sind die folgenden Felder für die Abfrage relevant:

ladedatum (ist klar denke ich)
tour_nr (Auftragsnummer)

ladestelle (enthält die Kundennummer der Ladestelle)
lds_geladen (enthält die Anzahl der geladenen Paletten)
lds_entladen (enthält die Anzahl der zurückgegebenen Paletten)

entladestelle (enthält die Kundennummer der Entladestelle)
els_geladen (enthält die Anzahl der geladenen Paletten)
els_entladen (enthält die Anzahl der agegebenen Paletten)

lds_beleg_nr (ist klar denke ich)
els_beleg_nr (ist klar denke ich)

lds_bemerkung (ist klar denke ich)
els_bemerkung (ist klar denke ich)

stockbooking (wert ob die Buchung eine Tour oder Lagerbuchung ist. Nur relevant für die Sortierung)

Mit den o.g. Feldern muss ein sogenannter Packmittelkontoausdruck für einen Kunden oder einen Unternehmer generiert werden. Der Kunde bzw. Unternehmer kann sowohl die Ladestelle als auch die Entladestelle sein. Beides muss jedoch auf einem Ausdruck stehen und auf dem Ausdruck gibt es nur die Spalten geladen und entladen.

Wenn er Ladestelle ist müssen die Felder lds_geladen sowie lds_entladen abgefragt werden, wenn er Entladestelle ist els_geladen und els_entladen.

Quasi sollte es auf dem Ausdruck dann z.B. so aussehen bei den Spalten geladen und entladen:


geladen entladen
wert:lds_geladen wert:lds_entladen (hier ist er Ladestelle)
wert:els_geladen wert:els_entladen (hier ist er Entladestelle)
wert:lds_geladen wert:lds_entladen (hier ist er wieder Ladestelle) usw. usw.

Jetzt noch die Summen der Spalten geladen und entladen auf dem Ausdruck. Ok.

Jetzt kommt das was mir richtig probleme bereitet. Aus den Summen muss die Differenz berechnet werden. Wenn er Ladestelle ist wird die Differenz errechnet aus lds_geladen - lds_entladen, wenn er Entladestelle ist wird die Differenz aus els_entladen - els_geladen errechnet. Jetzt kann es sein das er in einem Monat mal nur Ladestelle war oder nur Entladestelle. Er kann aber auch beides gewesen sein. Bei meinem SQL stimmen die Summen nie.

Hier das was ich gemacht habe. Aber ich hab mittlerweile so einen Knoten im Kopf, ich brauche eure Hilfe:

Gehen wir davon aus das die Kundennummer 80000 ist und diese befindet sich in $ident.

$query = "SELECT

ladedatum AS Ladedatum,
tour_nr AS 'Tour-Nr',
if (ladestelle ='$ident',lds_geladen,els_geladen) AS geladen,
if (ladestelle ='$ident',lds_entladen,els_entladen) AS entladen,
if (ladestelle !='$ident',lds_beleg_nr,els_beleg_nr) AS 'Beleg Nr',
if (ladestelle !='$ident',lds_bemerkung,els_bemerkung) AS 'Bemerkung',
stockbooking

FROM pbooking

WHERE (ladestelle = ".$ident." OR entladestelle = ".$ident.") AND (palart='".$part."') AND (deleted !=1) ORDER BY stockbooking = '1' DESC, ladedatum"

";

Das gibt mir schon mal die Spalten korrekt auf dem Ausdruck aus. Jetzt folgt das SQL für die Berechnungen:

SELECT "
. "sum(if (ladestelle ='".$ident."',lds_geladen,els_geladen)) ,"
. "sum(if(ladestelle ='".$ident."', lds_entladen, els_entladen)) ,"
. "if(ladestelle = ".$ident.",sum(if(ladestelle ='$ident', lds_geladen, els_geladen))-sum(if(ladestelle ='$ident', lds_entladen, els_entladen)), "
. "sum(if(ladestelle ='$ident', lds_i_entladen, els_i_entladen))-sum(if(ladestelle ='$ident', lds_i_geladen, els_i_geladen))) "
. "FROM pbooking WHERE (ladestelle = ".$ident." OR entladestelle = ".$ident.") AND (palart='".$part."') AND (deleted !=1)

Ich bin mir auch sicher face-smile das ein paar if's weg können. Aber das mal zu meinem Versuch das abzubilden was ich benötige... Ergebnisse stimmen so aber nicht

Jetzt schon Danke für jede Hilfe!!!

Content-Key: 271122

Url: https://administrator.de/contentid/271122

Printed on: April 23, 2024 at 08:04 o'clock

Member: Clijsters
Clijsters May 05, 2015 at 14:15:52 (UTC)
Goto Top
Hallo datadexx,
Wenn du das befolgst, werden die Leute auch hilfsbereit face-wink
Der Post ist so getippt sehr unübersichtlich...

Beste Grüße
Dominique
Member: datadexx
datadexx May 05, 2015 at 14:52:45 (UTC)
Goto Top
SORRY!!!

$query = "SELECT  

ladedatum AS Ladedatum,
tour_nr AS 'Tour-Nr',  
if (ladestelle ='$ident',lds_geladen,els_geladen) AS geladen,  
if (ladestelle ='$ident',lds_entladen,els_entladen) AS entladen,  
if (ladestelle !='$ident',lds_beleg_nr,els_beleg_nr) AS 'Beleg Nr',  
if (ladestelle !='$ident',lds_bemerkung,els_bemerkung) AS 'Bemerkung',  
stockbooking

FROM pbooking

WHERE (ladestelle = ".$ident." OR entladestelle = ".$ident.") AND (palart='".$part."') AND (deleted !=1) ORDER BY stockbooking = '1' DESC, ladedatum"  

";  

Summen, Differenz ermitteln:

SELECT "  
. "sum(if (ladestelle ='".$ident."',lds_geladen,els_geladen)) ,"  
. "sum(if(ladestelle ='".$ident."', lds_entladen, els_entladen)) ,"  
. "if(ladestelle = ".$ident.",sum(if(ladestelle ='$ident', lds_geladen, els_geladen))-sum(if(ladestelle ='$ident', lds_entladen, els_entladen)), "  
. "sum(if(ladestelle ='$ident', lds_i_entladen, els_i_entladen))-sum(if(ladestelle ='$ident', lds_i_geladen, els_i_geladen))) "  
. "FROM pbooking WHERE (ladestelle = ".$ident." OR entladestelle = ".$ident.") AND (palart='".$part."') AND (deleted !=1)  
Member: Clijsters
Clijsters May 05, 2015 at 15:00:43 (UTC)
Goto Top
Ouch...
Bilde doch erstmal in einem Step alle Summen der eventuell benötigten Werte in einer Tabelle ab.
Und dann - im nächsten Step - überlegst du dir, welche Werte du von welchen subtrahieren möchtest.

Das sollte sehr viel übersichtlicher ausgehen.

Und:
Bitte bearbeite deinen ursprünglichen Beitrag, entferne den Code, den du nun ein zweites Mal geposted hast und grenze die Tabellen etwas ab (z.B. Code oder Quote / oder Tabelle).
Es ist immernoch recht schwer leserlich.
Member: datadexx
datadexx May 05, 2015 at 15:05:06 (UTC)
Goto Top
Leider kann ich meinen ersten Post nicht dahingehend ändern, da zuviel Änderung. Will das System hier nicht.
Member: datadexx
datadexx May 05, 2015 at 15:09:55 (UTC)
Goto Top
Kannst Du mir das etwas genauer erklären wie Du das meinst mit alle Summen in einer Tabelle abbilden und dann entscheiden. Danke Dir!
Member: Biber
Biber May 05, 2015 updated at 16:26:22 (UTC)
Goto Top
Moin datadexx,

ich glaube, Clijsters meint es in etwa so:

Wenn du dieses hier mal (nur gedanklich!) verprobst:
SELECT 
  ladestelle,
  lds_geladen,
  0 as els_geladen,
  lds_entladen,
  0 as els_entladen
  FROM pbooking
  WHERE (ladestelle = ".$ident."   
  AND (palart='".$part."') AND (deleted !=1)  
Union ALL
 SELECT 
  entladestelle as ladestelle,
  0 as lds_geladen,
  els_geladen,
  0 as lds_entladen,
  els_entladen
  FROM pbooking
  WHERE (entladestelle = ".$ident."   
  AND (palart='".$part."') AND (deleted !=1)  

... dann könntest du mit zwei Such-Zugriffen auf deine pbookimg-Tabelle jeweils gezielt nach deiner "$ident" suchen.
Einmal explizit im Feld "ladestelle", einmal im Feld "entladestelle".
Das kann jeweils durch einen passenden Index unterstützt werden und ist - verglichen mit dem Konstrukt
"...WHERE (ladestelle = ".$ident." OR entladestelle = ".$ident.") ..AND (..)"
sicherlich gefühlte 50000x performanter.

Wenn du diese "virtuelle Tabelle" als ein inneres Select nutzt und dann Summen/Differenzen ermittelst, also so....
SELECT Sum(lds_geladen) as Lds_geladen
           , Sum(lds_entladen) as lds_entladen
           , Sum( lds_geladen -els_entladen) as DifferenzX,...
FROM (
  <<das UNION-Konstrukt von oben >>
) x
group by ladestelle
...dann hast du es ein wenig übersichtlicher.

(So zumindest würde ich meinen Vorkommentierer interpretieren.)

Grüße
Biber
Member: datadexx
datadexx May 05, 2015 at 16:11:44 (UTC)
Goto Top
Erst mal Danke Biber, ich werde das gleich testen.
Ich hab so ein Knoten im Kopf gerade...
Member: Clijsters
Clijsters May 05, 2015 at 16:32:57 (UTC)
Goto Top
Du hast es genau richtig interpretiert. In meinem Kopf sah es etwas anders aus, es sagt schlussendlich aber das gleiche.

Verzeiht, bin mal ausnahmsweise mit dem handy drin. Da schreibt es sich nicht sehr gut.

Beste Grüße
Dominique
Member: datadexx
datadexx May 05, 2015 at 17:03:09 (UTC)
Goto Top
Hey Biber und Co,

also performanter ist das auf jeden Fall schon mal und das scheint mir auch der richtige Weg zum Ziel zu sein.

Dein erstes SQL gibt 4 Spalten aus, auf dem Ausdruck habe ich ja nur 2 Spalten geladen, entladen. Ich muss also die Daten von lds_geladen und els_geladen untereinander in der Spalte geladen haben und die Daten von lds_entladen und els_entladen in der Spalte entladen.
Member: datadexx
datadexx May 05, 2015 at 17:13:07 (UTC)
Goto Top
Ok, das hab ich gerade umgeschrieben und passt.

Das problem was ich jetzt noch habe ist, wenn in der Abfrage nur Eregebnisse als Ladestelle herauskommen, wird geladen - entladen gerechnet für die Differenz der Summen, wenn nur Entladestellen als Ergebnis herauskommen wird jedoch entladen - geladen gerechnet für die Differenz der Summen. Wenn das Ergebnis Ladestellen und Entladestellen sind, wird wieder geladen - entladen gerechnet.

Wie mach ich das denn?
Member: Clijsters
Clijsters May 05, 2015 at 17:56:45 (UTC)
Goto Top
Hi datadexx,
Wenn du Bibers Beispiel richtig angewandt hast, solltest du doch alle Differenzen zugreifbar vor dir haben.

Und abhängig von deinen conditions schnappst du dir jetzt das Rechenergebnis, was du gerne hättest und druckst es auf das Blatt.

Oder verstehe ich deine Frage falsch?

Beste Grüße
Dominique
Member: Biber
Biber May 05, 2015 at 19:16:38 (UTC)
Goto Top
Moin datadexx,

ich galube, ich ahne das Missverständnis.

In dem unglücklichen Eröffnungsbeitrag, der auch mir zu sehr aus wenig strukturiertem Fliesstext bestand, stand
... Wenn er Ladestelle ist wird die Differenz errechnet aus lds_geladen - lds_entladen, wenn er Entladestelle ist wird die Differenz aus els_entladen - els_geladen errechnet. Jetzt kann es sein das er in einem Monat mal nur Ladestelle war oder nur Entladestelle. Er kann aber auch beides gewesen sein.

Demnach brauchst du in der "virtuellen Zwischentabelle" noch ein Feld mehr, d.h. je ein Feld für "Ladestelle" und eines für "Entladestelle".

Dann kannst du, wenn nur das Feld "Ladestelle" gefüllt ist, deine Rechnung gemäß Rechnungsvorschrift für Ladestellen machen und wenn nur das Feld "Entadestelle" gefüllt ist, deine Rechnung gemäß Rechnungsvorschrift für Entladestellen machen in dem äüsseren Select.

Unklar ist mir, wie das Ergebnis (in zwei Spalten dargestellt) sein soll, wenn diese IdentNr 4711 im Wonnemonat Mai tatsächlich Lade- und Entladestation war. Kannst du da mal ein Beispiel posten, zB wenn:

Ident_nr 4711 war Ladestelle, lds_geladen 50, lds entladen 45 und Ident_nr 4711 war auch Entladestelle, els_geladen 100, els_entladen 99.

Was steht in deinen erwähnten zwei Ausgabespalten?

Grüße
Biber
Member: datadexx
datadexx May 05, 2015 at 20:59:30 (UTC)
Goto Top
Hey Biber, Hi Clijsters,

das was Biber geschrieben hat ist es. Ich muss in meinem PHP Array die ladestelle und die entladestelle haben um entsprechend andere Werte ausgeben lassen zu können. Folgend ein Beispielbild von einem Ausdruck wie es korrekt ist. Darauf seht ihr die beiden Spalten geladen und entladen. Die Spalte geladen kann Werte aus lds_geladen oder els_geladen enthalten, geht auch. In dem Beispiel ist bei geladen der Wert 29 der Wert aus lds_geladen. Die Spalte entladen kann Werte aus lds_entladen und els_entladen enthalten. In dem Fall sind das alles Werte aus els_entladen. Die Berechnung der Summen in rot bzw. deren Anzeige funktioniert derzeit nur, weil der Wert 29 aus lds_geladen stammt und lds_geladen zur ladestelle gehört. Im Bild Beispiel 2 (das Gegenkonto) wird 0 angezeigt weil der Wert 29 dort aus els_geladen stammt, das gehört zur entladestelle und da komme ich nicht dran.

http://dexxware.de/beispiel.jpg

http://dexxware.de/beispiel2.jpg

DANKE Jungs bis hier her schon mal!
Member: datadexx
datadexx May 05, 2015 at 21:15:33 (UTC)
Goto Top
Das mit Ladestelle und Entladestelle nicht falsch verstehen im Sinne von das ident 4711 beides ist oder sein kann. das kann nicht vorkommen. Was ich meine wie in den Beispielbildern, das eine Zeile ladestelle sein kann, die nächste dann entladestelle, dann die nächste auch entladestelle, die nächste dann wieder ladestelle usw.

Man muss sich das so vorstellen, dass bei der einen Tour der Ident ladestelle war, bei der anderen war er entladestelle usw.

Wenn man dann die Summen der Paletten aus geladen und entladen subtrahiert ergibt sich daraus für den Monat die Differenz. Das Ergebnis ist dann ein Paletten Guthaben oder Paletten Schulden.

Jetzt ist es aber so, das wenn nur der Ident nur entladestelle ist, genau ungekehrt gerechnet werden muss also entladen - geladen...
Member: Clijsters
Clijsters May 05, 2015 at 21:31:27 (UTC)
Goto Top
... Also die Differenzen zeilenweise errechnet werden und am Ende je Spalte eine Summe gebildet wird?

Ich komme gerade nicht ganz hinterher. Versuche es nach einem kurzen Aufenthalt im Bett erneut.
Bis morgen!
Member: Biber
Biber May 06, 2015 updated at 07:59:54 (UTC)
Goto Top
Moin datadexx,

auch mich lässt du jetzt eher ein bisschen verwirrter zurück als vorher.

So wie das Bildchen aussieht, werden die Zahlen ermittelt nach -"ident_nr" und tja, jetzt muss ich raten - nach Datum oder nach BelegNr und gefiltert nach Zeitraum (zB. April 2015)

Okay, dann würde ich auch erwarten, dass diese Kriterien auch in deiner SSQl-Skizze oben auftauchen in den GROUP BY und WHERE-Klauseln.

Dem ist aber nicht so.
Mit dem obigen Ansatz bekommst du doch nur eine Zeile, also die Summenzeile.
Alles andere hast du schon/ermittelst es auf andere Weise?

Anders formuliert: deine beiden "Ergebnisspalten" - von denen willst du genau eine Zeile haben (die mit der Summe) oder willst du eine Zeile haben je Beleg oder Datum + eine Summenzeile?

Grüße
Biber
Member: datadexx
datadexx May 06, 2015 at 08:47:57 (UTC)
Goto Top
Moin Jungs,

sorry gestern war vom denken her nicht mein Tag...

Folgend der Code der auch die Ausgabe der Beispielbilder generiert:

Der Code holt mir erstmal die Daten aus dem Monat was $ident dort hatte und generiert die Zeilen. Natürlich habe ich den performanteren Code von Biber dazu genutzt. Hier läuft soweit auch alles so wie es soll.

SELECT 
  ladedatum AS Ladedatum,
  tour_nr AS 'Tour-Nr',  
  lds_geladen as geladen,
  lds_entladen as entladen,
  lds_beleg_nr as 'Beleg Nr',  
  lds_bemerkung as 'Bemerkung',  
  stockbooking
  FROM pbooking
  WHERE (ladestelle = '".$ident."' AND palart='".$part."' AND deleted !=1 AND MONTH(ladedatum) = ".$dayfilter.")  
Union ALL
 SELECT 
  ladedatum AS Ladedatum,
  tour_nr AS 'Tour-Nr',  
  els_geladen as geladen,
  els_entladen as entladen,
  els_beleg_nr as 'Beleg Nr',  
  els_bemerkung as 'Bemerkung',  
  stockbooking
  FROM pbooking
  WHERE (entladestelle = '".$ident."' AND palart='".$part."' AND deleted !=1 AND MONTH(ladedatum) = ".$dayfilter.")";  
  ORDER BY stockbooking = '1' DESC, ladedatum  

Der folgende Code soll jetzt die Summen und Differenzen dazu ermitteln. Hier hab ich auch den Code von Biber wieder genutzt.
Mit $summen = HoleSQLArray($summenQuery) erzeuge ich mir dann ein Array von der Abfrage von dem aus ich die Werte ausgeben kann. Hier komme ich aber nicht an die entladestelle.

SELECT 
Sum(lds_geladen) as lds_geladen
, Sum(lds_entladen) as lds_entladen
, Sum(els_entladen) as els_entladen
, Sum(els_geladen) as els_geladen
, Sum( lds_geladen - lds_entladen) as Differenz_ladestelle
, Sum( els_entladen - els_geladen) as Differenz_entladestelle 
, Sum(lds_geladen - els_entladen) AS Differenz   
, Sum(lds_entladen - els_geladen) AS DifferenzX  
FROM (
  SELECT   
  ladestelle,
  lds_geladen,
  0 as els_geladen,
  lds_entladen,
  0 as els_entladen
  FROM pbooking
  WHERE (ladestelle = '".$ident."' AND palart='".$part."' AND deleted !=1 AND MONTH(ladedatum) = ".$dayfilter.")  
Union ALL
 SELECT 
  entladestelle,
  0 as lds_geladen,
  els_geladen,
  0 as lds_entladen,
  els_entladen
  FROM pbooking
  WHERE (entladestelle = '".$ident."' AND palart='".$part."' AND deleted !=1 AND MONTH(ladedatum) = ".$dayfilter.")  
) x
group by ladestelle
";  
$summen = HoleSQLArray($summenQuery);

Könnte man jetzt so sehen Biber, das ich pro Beleg-nr, Datum eine Zeile benötige. Für mich ist eine Zeile eine Tour. Ich benötige aber nicht die Summe und Differenz pro Zeile sondern von allen Zeilen aus dem Monat. Summe geladen - Summe entladen ergibt dann meine Differenz. Ist aber in dem Monat $ident nur Entladestelle gewesen muss Summe entladen - Summe geladen gerechnet werden.
Member: Clijsters
Clijsters May 06, 2015 at 09:49:33 (UTC)
Goto Top
Für mich ist eine Zeile eine Tour
Für mich ist eine Zeile, das was in der Datenbank oder der Ausgabe eine Zeile darstellt face-wink

Also...
Die Abhängigkeiten, was die Subtraktion der Summen angeht, kennen wir ja.
Die Summenbildung selbst kennen wir auch.

Das Ziel und dessen (gewünschter) Weg ist teilweise noch schleierhaft.
An welcher Stelle und unter welchen genauen Bedingungen entscheidet deine Anwendung denn jetzt gerade, ob es sich um eine Entladestelle, eine Ladestelle oder beides handelt? Hat sich daran etwas geändert?

Ist aber in dem Monat $ident nur Entladestelle gewesen muss Summe entladen - Summe geladen gerechnet werden.
Was gerade noch unklar ist:Wenn du "Summe" sagst, meinst du die Werte eines Monats? eines Vorgangs? des Ergebnisses?

Beste Grüße
Dominique

P.S.: Wo war noch gleich definiert, ob $ident nun Lade- und/oder Entladestelle ist?
Member: datadexx
datadexx May 06, 2015 at 10:49:34 (UTC)
Goto Top
Hi Dominique,

ob $ident Ladestelle oder Entladestelle ist, ergibt sich durch die Buchung. Ein Beispiel einer Buchung, ich hoffe somit wird das verständlich:

Bei einer Tour werden an der Ladestelle Paletten geladen, diese Ladestelle ist sagen wir mal $ident=4711. An der Entladestelle werden Paletten abgeladen, hier ist $ident aber nicht 4711. Wird auch nie vorkommen. Bei einer anderen Tour ist die Ladestelle $ident=4811 und die Entladestelle $ident=4711. Beide Touren sind im Mai durchgeführt worden. Somi habe ich im Mai $ident=4711 einmal als Ladestelle, das andere mal als Entladestelle. Die erste Abfrage ermittelt das jetzt. Sie findet $ident=4711 als Ladestelle mit den Feldern lds_geladen und lds_entladen und generiert eine Zeile mit den Daten wie in den Beispielbildern zu sehen. Der Wert von lds_geladen steht jetzt in der Spalte geladen und der Wert aus lds_entladen in der Spalte entladen auf dem Ausdruck (siehe Beispielbild). Dann findet die Abfrage $ident=4711 als Entladestelle mit den Feldern els_geladen und els_entladen und generiert eine neue Zeile. Der Wert els_geladen ist auf dem Ausdruck in der Spalte geladen zu finden und els_entladen in der Spalte entladen. So baut sich das Ganze auf. Quasi wie eine "Excel" Tabelle. Jetzt brauche ich die Summen der Spalten geladen und entladen die auf dem Beispielbild unter den Spalten in rot stehen. Danach müssen die beiden Summen der Spalten geladen und entladen voneinander subtrahiert werden, damit ich die Differenz der Summen (geladen - entladen) erhalte um am Ende zu wissen ob der Transporteur uns Paletten schuldet oder wir ihm.

Jetzt kann der Fall auftreten, das $ident=4711 im Mai aber nur Entladestelle war. Die erste Abfrage findet ihn als Entladestelle und holt die Daten von els_entladen und els_geladen in die Spalten geladen (els_geladen) und entladen (els_entladen). In diesem Fall brauche ich dann die Summe von els_geladen und els_entladen, muss jedoch zur Berechnung der Differenz els_entladen - els_geladen (bzw. entladen - geladen) rechnen und die Werte ausgeben können. Das aber nur in dem Fall, das $ident=4711 nur Entladestelle war im Monat Mai und nicht auch Ladestelle, also die erste Abfrage findet ihn nur als Entladestelle mit einer oder auch mehreren Zeilen.

Beispielbilder der Buchungsmaske:

http://dexxware.de/buchung.jpg

http://dexxware.de/buchung2.jpg

Hoffe das ihr das versteht.
Member: Biber
Biber May 06, 2015 updated at 12:04:45 (UTC)
Goto Top
Moin datadexx,

okay, wir tasten uns voran...

Wenn ich es richtig interpretiere, dann brauchst du doch für deinen Auswerte-Monat mehrere "Ergebniszeilen" für diese $ident_nr" 4711, die dann in Rohform (vor dem Summieren) so aussehen:

Typ; Identnr, Datum, Tour; Belegnr, aufgeladen abgeladen
Ladestelle 4111 06.04.2015 Tour20 BelegNr 777, 29, 0
Abladestelle, 4711, 08.04.2015, Tour34, Belegnr (leer), 0, 34
Ladestelle 4111 16.04.2015 Tour66 BelegNr 666, 21, 0
-> das ware also skizziert die Struktur, die das Union-Konstrukt bekommen muss und auf dem du dann ein GROUP BY ident_nr, Typ, Datum, Tour, Belegnr machen kannst

Frage: Sind das jetzt auch deine Kriterien für die Einzelzeilen?
Sprich -
- Für jede Auf-/Abladebuchung gibt es ein Datum/ohne Datum keine Buchung?
- eine Buchung kann eine "Tour"-Nummer haben, muss aber nicht?
- eine Buchung kann eine "Beleg"-Nummer haben, muss aber nicht?
- Eine Tour kann über mehrere Tage gehen und wenn ja - soll eine Zeile je Datum herauskommen oder ein Zeile je Tour?

Sorry für die vielen Rückfragen, aber aus dem Bild der "Buchunsmaske" ist nicht ganz klar, was nun Pflichtfelder sind und welche eher optional.

Und meine praktischen Erfahrungen im Palettenverteilgeschäft sind eher gering.

Grüße
Biber
Member: datadexx
datadexx May 06, 2015 at 13:14:26 (UTC)
Goto Top
Hi Biber,

deine Rohform ist korrekt und kein Sorry für Rückfragen, das Palettengeschäft ist echt ne komplizierte Angelegenheit!

Pflichtfelder sind alle ausser Tour-Nr, beleg-nr und bemerkung.

Zu:

- Für jede Auf-/Abladebuchung gibt es ein Datum/ohne Datum keine Buchung? soweit richtig, jede buchung erfasst quasi das aufladen und das abladen der tour

- eine Buchung kann eine "Tour"-Nummer haben, muss aber nicht? richtig

- eine Buchung kann eine "Beleg"-Nummer haben, muss aber nicht? richtig

- Eine Tour kann über mehrere Tage gehen und wenn ja - soll eine Zeile je Datum herauskommen oder ein Zeile je Tour?

eine tour kann nicht, jedenfalls nicht für die Buchung, über mehrere Tage gehen. Ladedatum ist der tag an dem die ladung aufgenommen wurde und ist auch in erster Linie nur relevant um die Tour im richtigen Monat zu erfassen. Wenn er z.B. am 29.04. Ladung aufgenommen hat, aber erst am 02.05. abgeladen hat ist das völlig egal. Ladedatum=Erfassungsmonat. Somit eine Zeile pro Tour.
Member: datadexx
datadexx May 08, 2015 at 14:06:23 (UTC)
Goto Top
Hi Jungs,

ich bin jetzt eine Woche in Urlaub. Es wäre toll wenn wir danach an der Stelle hier weitermachen könnten.

Bis dahin nochmals vielen Dank Biber und Dominique.

Greetz datadexx
Member: Biber
Biber May 08, 2015 at 14:08:54 (UTC)
Goto Top
moin datadexx,

gerne.
Bis dahin schönen Urlaub.

Grüße
Biber
Member: Clijsters
Clijsters May 08, 2015 at 14:32:27 (UTC)
Goto Top
Hallöchen,

Von mir* auch!

Beste Grüße
Dominique

*...Der jetzt auch eine Woche Urlaub hat face-smile
Member: datadexx
datadexx May 08, 2015 at 14:42:11 (UTC)
Goto Top
Hi Jungs,

vielen Dank! Bis in einer Woche dann!

Greetz datadexx
Member: datadexx
datadexx May 11, 2015 at 04:36:55 (UTC)
Goto Top
Hab ich ja jetzt erst gesehen, Dir auch einen schönen Urlaub Dominique!
Member: datadexx
datadexx May 20, 2015 at 17:29:06 (UTC)
Goto Top
Hi Biber, Hi Dominique,

bin wieder aus dem Urlaub zurück und ab morgenfrüh auch wieder am Start.
Wäre cool, wenn wir dann gemeinsam nach der Lösung schauen könnten.

So wie Biber in einem vorigen Post ja bereits erkannt hat, brauchen wir noch in dem Konstrukt die Entladestelle um eine entsprechende Ausgabe zu generieren.

Dominique, ich hoffe Du hattest auch einen tollen, erholsamen Urlaub.

Greetz datadexx
Member: Biber
Biber May 28, 2015 updated at 14:49:32 (UTC)
Goto Top
Moin datadexx,

so, versuchen wir mal, diese Kuh vom Eis zu holen.

Mein Ansatz wäre jetzt, die "inneren Select" um ein Feld zu erweitern, damit du zwischen "Ladestelle" und "Entladestelle" unterscheiden kannst.

Also so:
  SELECT 
  'L' as LadeEntlade    
  ladestelle,
  lds_geladen,
  0 as els_geladen,
  lds_entladen,
  0 as els_entladen
  FROM pbooking
  WHERE (ladestelle = '".$ident."' AND palart='".$part."' AND deleted !=1 AND MONTH(ladedatum) = ".$dayfilter.")  
Union ALL
 SELECT 
  'E' as LadeEntLade  
  entladestelle,
  0 as lds_geladen,
  els_geladen,
  0 as lds_entladen,
  els_entladen
  FROM pbooking
  WHERE (entladestelle = '".$ident."' AND palart='".$part."' AND deleted !=1 AND MONTH(ladedatum) = ".$dayfilter.")  
) x
group by ladestelle, LadeEntlade

Dann sollte es möglich sein, in einer aussen liegenden SUM()-Aggregation eine CASE WHEN-Bedingung einzubauen.

Bitte prüfe doch aber erstmal dieses "innere Select" auf ein paar Beispieldaten, ob wir damit in die richtige Richtung gegeh.
möchte mich da lieber schrittweise rantasten - ich kann deine Daten hier nicht sinnvoll simulieren.

P.S.
Aber falls du da für eine ident_nr und einen Monat ein paar realitätsnahe Beispieldaten hast, dann lässt es sich schon nachbilden.
D.h. wenn es meinetwegen so jeweils 3-5 Sätze für die Identnr 4711 als Ladestelle/Entladestelle für einen Moant gibt...

Grüße
Biber
Member: datadexx
datadexx May 28, 2015 at 16:02:55 (UTC)
Goto Top
Hi Biber,

zu Deinem PS: werde heute Abend hier noch ein paar Datensätze zur Verfügung stellen und jetzt gleich mal das innere SELECT testen.

DANKE!

Greetz datadexx
Member: datadexx
datadexx May 28, 2015 at 18:52:40 (UTC)
Goto Top
Hi Biber,

ich hab Dir per pm eine sql Datei gesendet mit der Tabellen Struktur und echten Daten. Außerdem stehen in der Datei Abfragen, die nach deinem Beipiel vom letzten Post im inneren select L und E enthalten und einmal nur E + Erklärung was dann vom äußeren Summen select ausgegeben werden müsste.

Ich hoffe Du kannst das mal bei dir in eine Mysql DB schmeißen um das so besser testen bzw. durchspielen zu können.

L und E kennzeichnen schon mal korrekt die Zeilen, das habe ich getestet.

Greetz Datadexx
Member: Clijsters
Clijsters May 29, 2015 at 07:36:59 (UTC)
Goto Top
Tach, die Herren

Ich bin leider nicht mehr dazu gekommen, weiter zu folgen. Scheint aber, als kommt ihr weiter.

Ja, urlaub war super face-smile und selbst?

Beste Grüße
Dominique
Member: datadexx
datadexx May 29, 2015 at 07:48:38 (UTC)
Goto Top
Hi Dominique,

ja cool, mein Urlaub war auch bestens.

Ja wir kommen weiter, ich habe Biber gestern eine sql Datei zukommen lassen damit er das bei sich besser nachvollziehen kann. Ich denke wenn die CASE WHEN Bedingung jetzt noch drin ist haben wir die "Kuh vom Eis geholt".

Gruß datadexx
Member: Biber
Biber Jun 01, 2015 updated at 13:08:16 (UTC)
Goto Top
Moin datadexx,

sorry für die späte Rückmeldung - ich hatte ungeplanterweise ein längeres relativ computerfreies Wochenende.

Habe mir jetzt mal das Ganze mit deinen Daten und deinen Testqueries angeschaut.

Mir ist nur noch nicht klar, ob bzw was jetzt noch fehlt.

die geforderten Daten sind eigentlich doch schon abgreifbar.
SELECT  ladestelle
--  Sum(lds_geladen) as lds_geladen
--, Sum(lds_entladen) as lds_entladen
-- , Sum(els_entladen) as els_entladen
-- , Sum(els_geladen) as els_geladen 
, Sum(lds_geladen - els_entladen) AS X   
, Sum(lds_entladen - els_geladen) AS Y  
FROM (
SELECT 
  'L' as LadeEntlade,    
  ladestelle,
  lds_geladen,
  0 as els_geladen,
  lds_entladen,
  0 as els_entladen
  FROM pbooking
  WHERE (ladestelle = '80246' AND palart='H1' AND deleted !=1 AND MONTH(ladedatum) = 4)  
Union ALL
 SELECT 
  'E' as LadeEntlade,  
  entladestelle as ladestelle,
  0 as lds_geladen,
  els_geladen,
  0 as lds_entladen,
  els_entladen
  FROM pbooking
  WHERE (entladestelle = '80246' AND palart='H1' AND deleted !=1 AND MONTH(ladedatum) = 4)  
) x
group by ladestelle

Resultset wäre dann sowas wie
LADESTELLE | X | Y  
-----------+---+----
     80246 | 0 | -10


--> diese Query würde als Felder X und Y die geforderten Differenzen für eine Ident_nr bringen.
Okay, die Differenzierung nach Lade/Entladestelle ist zwar verfügbar, wird aber nicht genutzt.

Was fehlt denn noch?

Grüße
Biber
Member: datadexx
datadexx Jun 01, 2015 at 10:20:00 (UTC)
Goto Top
Hi Biber,

kein Thema!

Eigentlich hast Du recht, denn entweder ist X oder Y = 0. Könnte ich also abfragen ob X oder Y 0 ist und dann den Wert der nicht 0 ist ausgeben.

Besser wäre natürlich, wenn in dem äußeren select zb. nur X vorkommen würde und X entsprechend dem vorkommen von L, L und E oder nur E berechnet würde...

Gruß datadexx
Member: datadexx
datadexx Jun 01, 2015 at 10:24:39 (UTC)
Goto Top
Beim vorkommen von L oder L+E im inneren select wird X benötigt, bei nur E wird Y benötigt.
Member: Biber
Solution Biber Jun 01, 2015, updated at Aug 18, 2015 at 12:27:30 (UTC)
Goto Top
Moin datadexx,

dann liesse es sich vermutlich reduzieren auf
SELECT  ladestelle
--  , ladeentlade
  , Sum(lds_geladen) as lds_geladen
 , Sum(lds_entladen) as lds_entladen
  , Sum(els_entladen) as els_entladen
  , Sum(els_geladen) as els_geladen 
, Sum( case when ladeentlade ='L' then lds_geladen - els_entladen   
            when ladeentlade ='E' then lds_entladen - els_geladen  
       end ) as diffXY        
FROM (
SELECT 
  'L' as LadeEntlade,    
  ladestelle,
  lds_geladen,
  0 as els_geladen,
  lds_entladen,
  0 as els_entladen
  FROM pbooking
  WHERE (ladestelle  in ('80246', '80190') AND palart='H1' AND deleted !=1 AND MONTH(ladedatum) = 4)  
Union ALL
 SELECT 
  'E' as LadeEntlade,  
  entladestelle as ladestelle,
  0 as lds_geladen,
  els_geladen,
  0 as lds_entladen,
  els_entladen
  FROM pbooking
  WHERE (entladestelle in ('80246', '80190') AND palart='H1' AND deleted !=1 AND MONTH(ladedatum) = 4)  
) x
group by ladestelle -- , ladeentlade
;

ResultSet wäre dann
LADESTELLE | LDS_GELADEN | LDS_ENTLADEN | ELS_ENTLADEN | ELS_GELADEN | DIFFXY
-----------+-------------+--------------+--------------+-------------+-------
     80190 |           0 |           10 |            0 |          10 |    -10
     80246 |           0 |            0 |            0 |          10 |    -10

(eigentlich nur benötigt sind "Ladestelle" und "DiffXY")

Ich habe jetzt mal zwei ident_nr in die Query genommen und zeige nicht nur das eine benötigte Feld "DiffXY" an, sondern zum Nachvollziehen auch noch die "Einzelsummanden"-Felder für lds_geladen, lds_entladen etc.
Diese vier Zeilen " , Sum(lds_geladen) as lds_geladen" + 3 danach können natürlich entfallen in der echten Query.

Andersrum: wenn du zum Debuggen noch eine Detailebene mehr brauchst, dann entferne die beiden Kommentar-Kennzeichen "--" vor dem Wort "ladeentlade".

Da musst du mal prüfen, ob das Ergebnis sinnhaft und plausibel ist oder nicht - das kann ich fachlich nicht beurteilen.

Grüße
Biber
Member: datadexx
datadexx Jun 01, 2015 at 14:08:27 (UTC)
Goto Top
Hi Biber,

nimm mal bitte nur 80190 und entferne die Kommentare für ladeentlade. Als Ergebnis erhältst Du ja 2 Zeilen für 80190. Einmal als L und einmal als E. Er hat also 10 entladen und 10 geladen. Da müsste also 0 raus kommen anstatt -10.

Greetz datadexx
Member: datadexx
datadexx Jun 01, 2015 at 14:21:20 (UTC)
Goto Top
Ich glaube das ist alles noch viel komplizierter als gedacht...
Member: Biber
Biber Jun 01, 2015, updated at Jun 03, 2015 at 07:41:59 (UTC)
Goto Top
Moin datadexx,

da bin ich ganz bei dir - mir kam es auch nicht plausibel vor.

Ich vermute mal, die "richtige" Summenberechnung sollte lauten wie bei "DiffYZ", die du mal zum Vergleich einbauen kannst in obiges Select.

...
, Sum( case when ladeentlade ='L' then lds_geladen - els_entladen   
            when ladeentlade ='E' then lds_entladen - els_geladen  
       end ) as diffXY        
, Sum( case when ladeentlade ='E' then els_geladen - els_entladen   
            when ladeentlade ='L' then lds_geladen - lds_entladen  
       end ) as diffYZ        
...

Passt das besser?

Grüße
Biber
P.S.
BTW - Ladestelle/Entladestelle bzw Ident_nr und auch der Rückgabewert von Month(datumswert) sind numerisch.
Beides wird aber in deinen Queries als Text-Wert behandelt bzw.angegeben. Muss nicht sein.
Die überflüssige implizite Casterei ... WHERE (entladestelle in ('80246', '80190') kann entfallen.
Reichen würde ein WHERE (entladestelle in (80246, 80190) .
Member: datadexx
datadexx Jun 01, 2015 updated at 14:39:43 (UTC)
Goto Top
jep, da kommt bei diffYZ 0 raus. Frage ist jetzt nur wann wird was wie ausgegeben...
Member: datadexx
datadexx Jun 01, 2015 at 16:48:35 (UTC)
Goto Top
Hey Biber,

das Ganze muss jetzt noch einem Praxistest unterzogen werden (den mache ich nicht selbst), aber soweit ich das sehe funktioniert das wie folgt:
Manchmal sieht man vor Bäumen den Wald nicht mehr...

SELECT 
Ladeentlade AS LE,
Sum(lds_geladen) as lds_geladen
, Sum(lds_entladen) as lds_entladen
, Sum(els_entladen) as els_entladen
, Sum(els_geladen) as els_geladen
, SUM(lds_geladen + els_geladen) AS A
, SUM(lds_entladen + els_entladen) AS B

FROM ( ...

Jetzt hol ich mir das als PHP Array und kann folgendes machen (Beispiel):

if ($LE == 'L')  
{
      $diff = $sumA - $sumB
}
else
{ 
      $diff = $sumB - $sumA
}
Member: Clijsters
Clijsters Aug 18, 2015 at 11:38:01 (UTC)
Goto Top
Darf man mal ganz interessiert wieder einspringen...

Was machen deine Paletten?

Habe leider irgendwann den Faden verloren.
Member: datadexx
datadexx Aug 18, 2015 at 12:27:12 (UTC)
Goto Top
Hi Clijsters,

sorry hab ganz vergessen das Thema hier abzuschliessen.

Im Gesamten haben hier alle Antworten von Dir und von Biber zur Lösung beigetragen. Vielen Dank dafür noch mal!!! Die optimierte Abfrage von Biber bzgl. der Summenberechnung allein war schon super. Letztendlich funktioniert es so wie in meinem letzten Beitrag gepostet mit der PHP if Abfrage wenn "L" oder "E" als Ergebnis heraus kommt dann rechne bla bla... Manchmal ist man halt so versteift, das man die einfachen Dinge nicht mehr sieht...

Wie gesagt vielen Dank noch mal an euch beide!!!