geschachtelte Abfrage

quidnovi

Erfahrenes Mitglied
Hi @ all,

addiere in der DB Stunden zusammen, um etwaige Änderungen durchzuführen - wenn nötig.

Zuerst frage ich alle Einträge ab und wenn die Summe der Stunden die Grenze von 8,5 übersteigt, dann hole ich mir den betreffenden Eintrag der zu ändern ist. Dieser Eintrag hat immer den Wert 16:30. Die Abfragen schauen so aus:
PHP:
// 1. Abfrage
$sql = "SELECT *,SUM(hGesamt) as 'summe' FROM r_abrechnung ".
			   "WHERE persnr ='".$_SESSION['user_persnr']."' ".
			   "AND status = 1 ".
			   "AND datTag = '".$datTag."' ".
			   "group BY 'dat' ORDER BY 'id' DESC";

	    	   $res = mysql_query ($sql) or die (mysql_errno() . ": Keine Verbindung zu \"r_abrechnung\"! " . mysql_error());

	    	   while ($row = mysql_fetch_object($res)){
				   if($row->summe > 8.50){

				   	   $erg1 = ($row->summe - 8.50);


				   	   // 2. Abfrage
					   $que = "SELECT * FROM r_abrechnung ".
					   		  "WHERE datTag = ".$datTag." ".
					   		  "AND auftragsNr = ".$auftragsNr." ".
					   		  "AND end = '16:30' ".
					   		  "AND persnr =".$_SESSION['user_persnr']."";
					   $erg = mysql_query($que) or die("MySQL-Fehler " . mysql_error() . $que)
					   while ($zeile = mysql_fetch_object($erg)){
			                            echo "<br />";
			                            echo $zeile->begin;
			                            echo "<br />";
			                            echo $zeile->end;
			                            echo "<br />";
			                            echo $zeile->arbBericht;
					   }
		               ......

Ich bekomme keine Ausgabe von der 2. Abfrage. Wenn ich jetzt die while-Schleife entferne, dann bekomme ich nur die Daten des ersten Datensatzes.

Wie kann ich dieses Problem lösen? Kann mir bitte jemand die Schuppen von den Augen lösen?
Danke im Voraus
 
Habe nun den Fehler soweit eingrenzen können als dass zwei SELECT Abfragen hintereinander scheinbar nicht funktionieren.

Wie schon erwähnt, bekomme ich die Daten nur von der ersten Abfrage.

Nun brauche ich aber diese beiden Abfragen, denn nur wenn nach der ersten Abfrage die Gesamtstunden 8,5 übersteigen, dann muss ich den Eintrag mit dem gleichen Datum und dem Wert 16:30 bearbeiten.

Ich weiß leider keine Lösung. Bitte helft mir eine zu finden, danke
 
Hallo,

poste doch bitte mal die Tabellenstruktur und was du vorher im PHP-Skript machst.

Ansonsten:


- Zwei SELECTs nacheinander funktionieren problemlos. Wenn, dann ist es ein anderer Fehler.
Du solltest Feld / Spaltennamen nicht mit einfachen Hochkomma quoten
Deine erste Query wäre wahrscheinlich optimierbar. Du kannst mittels
SQL:
  SELECT...
 GROUP BY ...
HAVING SUM(hGesamt) > 8.5... 
 ORDER BY
die Resultate schon so einschränken, dass sie nur Ergebnisse liefern, die mehr als 8,5 Stunden beinhalten.
Deine erste Query aggregiert die Zeiten je Tag? Dann hast du für einen Mitarbeiter genau einen Datensatz und mehrere Datensätze durch die 2.Query für jeden Zeitblock, den ein Mitarbeiter erfasst hat? Wenn ja, dann ist die Spalte "end" doch nicht immer 16.30 Uhr, oder? Oder warum musst du genau diesen bearbeiten? Wenn deine Aufgabe ist, die Endzeit der Gesamtarbeitszeit je Tag anzupassen, dann geht das auch einfacher
Muss es eigentlich 16.30 Uhr sein, oder geht das System immer von festen Startzeiten wie 8.00 Uhr aus um dann auf 8,5 Stunden zu kommen?
Was ist die Variable $ergl - du benutzt sie nirgends weiter
Dein Quoting ändert sich von der ersten zur zweiten Abfrage:

1.Abfrage:
SQL:
AND datTag = '".$datTag."' ".
2.Abfrage:
SQL:
WHERE datTag = ".$datTag." ".

So richtig hab ich es nun nicht verstanden. Sollen die Änderungen weitgehend automatisch durch die Datenbank vorgenommen werden oder soll das über PHP geschehen?

Markus
 
Hi,

versuche nun dieses Tool zu erklären.

Mitarbeiter(MA) geben über ein Formular ihre geleiststen Stunden ein.
Die Arbeitszeit beginn zwischen 7:00 und 7:30 Uhr und endet um 12:00 Uhr.
Die Arbeitszeit am Nachmittag beginnt um 12:30 und ist nach oben hin offen - theoretisch.

Jetzt sind die geleisteten Stunden in gewisse Kategorien eingeteilt wie Normalarbeitsstunden, Überstunden aufbauend, Überstunden mit 50% und 100%.

Wenn nun die Tagesarbeitszeit von 7:00 - 12:00 und 12:30 - 16:30 (9,0 Stunden) reicht, dann gliedern sich die Stunden wie folgt:
7:00 - 12:00 = 5h (Kategorie oder Lohnart 1)
von 12:00 - 12:30 vorgeschriebene Mittagspause, welche in der Berechnung nicht berücksichtigt wird
12:30 - 16:00 = 3,5h (Kategorie oder Lohnart 1)
16:00 - 16:30 = 0,5h (Kategorie oder Lohnart 29, Überstunden aufbauend)

Der MA gibt natürlich nur von 7:00 - 12:00 und 12:30 - 16:30 ein.

In diesem Fall, habe ich es schon so, dass die Stunden bezogen auf den MA und den Tag addiert werden und das auch automatisch - so wie oben erwähnt - richtig in die DB geschrieben wird.

Das Prob liegt beim update:
Wenn nun der MA etwas an den Arbeitszeiten ändert, dann hat das Auswirkung auf die Gesamtstundenzahl.

Die 1/2 h Lohnart 29 kann nur zwischen 16:00 und 16:30 anfallen. Da gibt es Firmenintern keine Abweichung.


Sobald sich die Gesamtarbeitszeit von 8,5 auf 9,00h erhöht, wird bei dem Eintrag, welcher als Ende 16:30 enthält eine halbe stunde abgezogen. Dann wird diese 1/2h mit der Lohnart 29 neu - mit dem Datum und der Auftragsnummer - eingefügt.

Hier das Beispiel:

Eintrag vor dem update:
7:30 - 12:00 (Lohnart 1)
12:00 - 16:30 (Lohnart 1)

Nach dem update:
7:00 - 12:00 (La 1)
12:30 - 16:00 (La 1)
16:00 - 16:30 (La 29)

Natürlich muss das auch umgekehrt funktionieren. Also:
Vor dem update:
7:00 - 12:00 (La 1)
12:30 - 16:00 (La 1)
16:00 - 16:30 (La 29)

Nach dem update:
7:30 - 12:00 (La 1)
12:30 - 16:30 (La 1)

Die Tabellenstruktur:
id - int(11)
tag - int(5)
monat - int(5)
jahr - int(5)
datTag - date
auftragsNr - int(11)
arbBericht - text
begin - varchar(20)
end - varchar (20)
la - int(5)
laH - int(5)
lohn19 - int(5)
diaeten - int(5)
lohn8 - int(5)
kmAbFa - int(5)
persNr - int(11)
hGesamt - decimal(10,2)
status - int(5)
alias - int(20)
zeitstempel - timestamp

Ja, nu fällt mir auch nicht mehr dazu ein. Es ist ein wenig komplex - zumindest für meinen Level.

Hoffe, man kann damit etwas anfnagen. Bin für jede Hilfe dankbar
 
Hallo nochmal,

im ersten Schritt nach dem Update eines Zeiteintrages eines Benutzer hast du ja 3 Fälle zu unterscheiden.

a) Entweder er ändert seine Stunden, aber alles bleibt beim alten (Lohnart 1). Dann musst du ausser dem UPDATE des jeweiligen Eintrages nichts weiter machen.
D.h. der User hatte vorher weniger als 9 Stunden und nach dem Update immer noch. Oder er hatte vor dem Update 9 Stunden und nach dem Update ebenfals 9 Stunden

b) Der zweite Fall tritt ein, falls der jetztige Benutzer mehr als 8,5 Stunden erfasst hat (das weisst du ja nach dem Aufrufen der Update-Maske schon) und vor dem Aufruf der Updatemaske weniger als 9 Stunden hatte.
Dann kannst du den Eintrag mit dem Ende 16.30 Uhr ja direkt auf 16:00 UPDATEn und einen neuen Eintrag von 16:00-16:30 mit der Lohnart 29 per INSERT machen.

c) Der dritte Fall tritt ein, falls der jetzige Benutzer schon mehr als 8,5 Stunden erfasst hatte und das ganze nun wieder auf unter oder auf 8,5 Stunden sinkt.
Dann machst du ein DELETE auf den Eintrag mit der Lohnart 29 für den Eintrag mit Ende 16:30 Uhr und das wars.

Weiterhin finde ich, dass das Datenmodell eures Tools zu wünschen übrig lässt. Aber das nur am Rande.

Falls du weitere Hilfe oder Code benötigst oder gar nicht mehr weiter weisst, frag einfach noch einmal nach.

Markus
 
Hallo Markus,

danke für Deine Analyse. Habe das auch so angedacht, nur funktioniert das Ganze noch nicht so wie gewünscht.

In meinem Eröffnungsthread versuchte ich die Situation zu schildern. Dass 2 SELECT Abfragen nacheinander funktionieren, das weiss ich auch, nur stimmt das mit meinem Code nicht.

ich muss mir Deinen Tip mit "HAVING" mal ansehen wie das funktioniert, das habe ich noch nie gesehen.

Könntest Du mir bitte die Verbessungsvorschläge bezüglich dem Datenmodell posten? Vielleicht ergibt sich ja dadurch eine neue Abfragemöglichkeit.

Vielen dank im voraus
 
So, gehe das nun alles weniger kompliziert an.

Der Sinn des Ganzen ist eigentlich die Abrechnung am Ende des Tages.

Nun habe ich ein dropdown - Feld, in welchem man die Tage die abgerechnet werden sollen ausgewählt werden können.

Nun habe ich folgenden Code womit ich die gewünschten Tage abfrage und deren Stunden zusammenfasse:
PHP:
$sql = "SELECT *,SUM(hGesamt) as 'summe' FROM r_abrechnung WHERE datTag BETWEEN '$von' AND '$bis' GROUP BY 'persNr' ORDER BY 'datTag' asc";

Jetzt funktioniert das ja, nur bekomme ich nur die Daten eines Mitarbeiters, statt aller in dem betreffenden Zeitraum.


Ich sollte folgendes Ergebnis erzielen:
Mitarbeiter 1 - 12h, 2007-08-04
Mitarbeiter 2 - 5h, 2007-08-04
Mitarbeiter 1 - 6h, 2007-08-03
...

Das Ziel:
Die Stunden eines Mitarbeiters bezogen auf den Tag zu addieren.
Dann ändere ich gewisse Einträge wenn nötig.

Das ist der einfachere Weg, denke ich mal.

So nun meine Bitte: Erklärt mir bitte den Weg, wie ich das oben anvisierte Ergebnis erhalte.

Danke
 
Hallo,

das Ergebnis,was du erreichen möchtest, solltest doch schon durch deine Abfrage so oder so ähnlich zurück kommen:

Probier mal folgendes:

SQL:
SELECT persNr, datTag, SUM(hGesamt) as summe
  FROM r_abrechnung
 WHERE datTag BETWEEN '$von' AND '$bis' 
 GROUP BY persNr, datTag
 ORDER BY datTag;

Damit bekommst du alle Stunden je Mitarbeiter und Tag, auf dem erfasst wurde aufsteigend nach Datum sortiert.

Markus
 
Zuletzt bearbeitet:
Hallo,

jetzt habe ich mit folgender Abfrage:
PHP:
$sql = "SELECT * FROM r_abrechnung WHERE datTag BETWEEN '$von' AND '$bis' ORDER BY 'datTag' asc";

das Ergebnis in eine txt Datei geschrieben. Sieht so aus:
1.1.2007;10;155;1;5;
1.1.2007;20;155;1;4;
2.1.2007;20;100;1;5;
2.1.2007;20;100;1;4;

Erkläre:
Datum
Auftragsnummer(n):10, 20
Mitarbeiternummer(n): 155, 100
Lohnart: 1
Stunden pro Eintrag: 5, 4

Nun schauen die Einträge: a) 1.1.2007;20;155;1;4; und b) 2.1.2007;20;100;1;4;
in der DB so aus:
a) 12:30 - 16:30 (Lohnart 1)
b) 12:30 - 16:30 (Lohnart 1)

Jetzt muss ich die Einträge wie folgt ändern:
a) 12:30 - 16:00 (Lohnart 1)
16:00 - 16:30 (Lohnart 29)

b) 12:30 - 16:00 (Lohnart 1)
16:00 - 16:30 (Lohnart 29)

damit die txt Datei im Endeffekt so aussieht:
1.1.2007;10;155;1;5;
1.1.2007;20;155;1;3.5;
1.1.2007;20;155;29;0.5;

2.1.2007;20;100;1;5;
2.1.2007;20;100;1;3.5;
2.1.2007;20;100;29;0.5;


Hier glaube ich, dass nur mehr PHP weiterhilft. Nur wie? Es tut mir leid, aber ich wüsste nicht mal wo ansetzen.

Könnt Ihr mir bitte einen Ansatzpunkt nennen? Bitte, Danke
 
Hallo,

eigentlich ist dieser Thread hier zu schließen, denn die Sql Abfrage ist jetzt ja richtig, alles weitere betrifft ja PHP.

Deswegen stelle ich die weiteren Fragen im richtigen Board.

Danke für die Hilfe
 
Zurück