Shiggy Geschrieben 2. September 2013 Teilen Geschrieben 2. September 2013 (bearbeitet) Einen guten Morgen allerseits, im Rahmen eines Projekts habe ich mit Datenbanken zu tun. Diese ist eine ACCESS .mdb. Nun möchte ich aus meinen Tabellen folgende Daten haben: employeeNumber, name, phoneNumber, costCenter, lastMonthEndClosing, locked, wDate, comes, goes diese sind in den Tabellen: Employee, Person, Contact, Payment, TimeManagement, KeyInformation und Times (jede der Tabellen hat eine id-spalte. diese ist autogeneriert und somit einzigartig) Folgende SQL-Abfrage ist bereits erstellt, liefert aber nicht das richtige ergebnis. SELECT Employee.employeeNumber,name,phoneNumber,costCenter,lastMonthEndClosing,locked,wDate,comes,goes FROM ((((((Employee LEFT JOIN Person ON Person.employeeNumber = Employee.employeeNumber) LEFT JOIN Contact ON Contact.employeeNumber = Employee.employeeNumber) LEFT JOIN Payment ON Payment.employeeNumber = Employee.employeeNumber) LEFT JOIN TimeManagement ON TimeManagement.employeeNumber = Employee.employeeNumber) LEFT JOIN KeyInformation ON KeyInformation.employeeNumber = Employee.employeeNumber) LEFT JOIN Times ON Times.employeeNumber = Employee.employeeNumber AND )) ORDER BY Employee.employeeNumber ASC Bisher sieht es so aus dass mir die Abfrage für jeden Mitarbeiter der angelegt ist eine Zeile ausgibt und dazu die Zeit (aus der Times-Tabelle). Das sind im moment 4 Zeilen für den ersten Mitarbeiter in der Ausgabe. (also für jeden Eintrag in Times der mit dem Mitarbeiter verknüpft ist wird der Mitarbeiter mit den gebrauchten Daten ausgegeben) Beim zweiten Mitarbeiter ist wDate, comes und goes leer, so soll es auch sein. Wie kann ich nun diese SQL-Abfrage erweitern dass Sie mir nur 1x den ersten Mitarbeiter ausgibt mit dem letzten Eintrag in der Times-Tabelle? Es soll also jeder Mitarbeiter mit dem letzten Eintrag in der Times-Tabelle ausgegeben werden. Mit freundlichen Grüßen Shiggy Bearbeitet 2. September 2013 von Shiggy Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
uenetz Geschrieben 2. September 2013 Teilen Geschrieben 2. September 2013 Hallo! Ein Lösungsansatz wäre z.B.: Vor ORDER BY ein GROUP BY Employee.employeeNumber setzen. Und dann ORDER BY Times.employeeNumber DESC ... wenn ich das beim Überfliegen so richtig gesehen habe. Aber ... warum probierst Du es nicht einfach aus? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shiggy Geschrieben 2. September 2013 Autor Teilen Geschrieben 2. September 2013 Eine gute Idee. Habe es gerade getestet aber leider gibt er mir den Fehler hier aus: "Sie wollten eine Abfrage ausführen, die den angegebenen Ausdruck 'name' nicht als Teil der Aggregatfunktion einschließt" Ich weiß dass es am GROUP BY liegt weil ohne dieses funktioniert es. Ich habe es auch mal mit DISTINCT hinter dem SELECT versucht aber da gibt er immer noch 2 Datensätze für den einen mitarbeiter raus (beinahe richtig^^). die aktuelle abfrage sieht so aus: SELECT Employee.employeeNumber,name,phoneNumber,costCenter,lastMonthEndClosing,locked,wDate,comes,goes FROM ((((((Employee LEFT JOIN Person ON Person.employeeNumber = Employee.employeeNumber) LEFT JOIN Contact ON Contact.employeeNumber = Employee.employeeNumber) LEFT JOIN Payment ON Payment.employeeNumber = Employee.employeeNumber) LEFT JOIN TimeManagement ON TimeManagement.employeeNumber = Employee.employeeNumber) LEFT JOIN KeyInformation ON KeyInformation.employeeNumber = Employee.employeeNumber) LEFT JOIN Times ON Times.employeeNumber = Employee.employeeNumber) GROUP BY Employee.employeeNumber ORDER BY Times.employeeNumber DESC Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
uenetz Geschrieben 2. September 2013 Teilen Geschrieben 2. September 2013 Wenn ich das wieder überfliege ... sehe ich da, dass es eventuell an der Klammerung liegen könnte Aber ich denke Du schaffst das nun auch ohne Hilfe, oder? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shiggy Geschrieben 2. September 2013 Autor Teilen Geschrieben 2. September 2013 (bearbeitet) Nachdem ich dies nun mal mit verschiedenen Möglichkeiten (alle die mir aufgefallen sind) der Klammersetzung getestet habe kann ich sagen dass es so nicht so funktioniert wie ich das gerne hätte. das Problem für diese Fehlerausgabe lag an dem Group By. nachdem ich in dem Group By alle Felder die ich abfrage in meinem SELECT eingefügt habe hat es funktioniert. allerdings werden immernoch mehr als 2 Datensätze ausgegeben und zwar wenn die Zeiten in der Times-Tabelle unterschiedlich sind. wenn ich zwei datensätze in der Times-tabelle habe und diese wie folgt aufgebaut sind: emp.Number, datum, 8:00Uhr, 16Uhr. dann werden diese gruppiert auf 1 datensatz im endergebnis. wenn aber ein dritter drinnen ist mit einer anderen Uhrzeit (egal ob comes oder goes) dann macht er im endergebnis dafür eine Zeile mehr. Den selben effekt hatte ich auch mit Distinct. Diese Abfrage funktioniert wie gerade beschrieben. SELECT Employee.employeeNumber,name,phoneNumber,costCenter,lastMonthEndClosing,locked,wDate,comes,goes FROM (((((Employee INNER JOIN Person ON Person.employeeNumber = Employee.employeeNumber) INNER JOIN Contact ON Contact.employeeNumber = Employee.employeeNumber) INNER JOIN Payment ON Payment.employeeNumber = Employee.employeeNumber) INNER JOIN TimeManagement ON TimeManagement.employeeNumber = Employee.employeeNumber) INNER JOIN KeyInformation ON KeyInformation.employeeNumber = Employee.employeeNumber) LEFT JOIN Times ON Times.employeeNumber = Employee.employeeNumber GROUP BY Employee.employeeNumber, name, phoneNumber, costCenter, lastMonthEndClosing, locked, wDate, comes, goes ORDER BY Employee.employeeNumber ASC [table=width: 500, class: grid, align: left] [tr] [td]1[/td] [td]Schall Rauch[/td] [td]0123456789[/td] [td]0[/td] [td]0[/td] [td]0[/td] [td]20130805[/td] [td]08:00[/td] [td]12:00[/td] [/tr] [tr] [td]1[/td] [td]Schall Rauch[/td] [td]0123456789[/td] [td]0[/td] [td]0[/td] [td]0[/td] [td]20130805[/td] [td]12:00[/td] [td]16:30[/td] [/tr] [tr] [td]1[/td] [td]Schall Rauch[/td] [td]0123456789[/td] [td]0[/td] [td]0[/td] [td]0[/td] [td]20130805[/td] [td]19:00[/td] [td]23:00[/td] [/tr] [tr] [td]2[/td] [td]Dieter Abel[/td] [td][/td] [td]0[/td] [td]0[/td] [td]0[/td] [td][/td] [td][/td] [td][/td] [/tr] [/table] es gibt den Datensatz in Spalte 1 in der times-tabelle (20130805.08:00,12:00) zwei mal. er wurde also gruppiert. das ergebnis sollte aber vorsehen dass ich nur den letzten Eintrag dort stehen habe für den Mitarbeiter 'Schall Rauch'. also (20130902,'19:00','23:00'). wenn ich hier in der Order By an stelle von Employee die Times-Tabelle verwende dann funktioniert die gesamte query nichtmehr. ich weiß nicht, entweder muss ich das ganze umschreiben und mit das Ergebnis mit WHERE und usw. zusammenbauen oder ich sehe die Lösung nicht weil ich blind bin. Wäre super wenn ich noch etwas hilfe bekäme. Liebe Grüße ein verzweifelndes Shiggy ^^ Bearbeitet 2. September 2013 von Shiggy Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shiggy Geschrieben 2. September 2013 Autor Teilen Geschrieben 2. September 2013 Habe soeben die Meldung erhalten dass wir die Zeiten nun wohl doch nicht brauchen. >.< Danke für die Hilfe. Villeicht werde ichs in den nächsten Tagen nochmal in Angriff nehmen ^^ Greetz Shiggy Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shiggy Geschrieben 17. September 2013 Autor Teilen Geschrieben 17. September 2013 Hallo liebe Mitprogrammierer ich arbeite momentan an der oben beschriebenen Methode welche für jeden angelegten Mitarbeiter (Tabelle: Employee) den Namen (Tabelle: Person), Telefonnummer (Tabelle: Contact), Kostenstelle (Tabelle: Payment), Monatsabschluss (Tabelle: TimeManagement) und (das wichtige woran ich scheitere) wann er sich das letzte mal angemeldet hat (comes) und wann er sich das letzte mal abgemeldet hat (goes) ink. Datum (wDate). Employee, Person, Contact, Payment, TimeManagement, Times, das sind die Tabellen die involviert sind. Meine aktuelle SQL-Abfrage sieht folgendermaßen aus: SELECT e.employeeNumber,name,phoneNumber,pa.costCenter,lastMonthEndClosing,locked, wDate, comes, goes FROM (((((Employee e LEFT JOIN Person p ON p.employeeNumber = e.employeeNumber) LEFT JOIN Contact c ON c.employeeNumber = e.employeeNumber) LEFT JOIN Payment pa ON pa.employeeNumber = e.employeeNumber) LEFT JOIN TimeManagement tm ON tm.employeeNumber = e.employeeNumber) LEFT JOIN KeyInformation ki ON ki.employeeNumber = e.employeeNumber) LEFT JOIN Times t on t.employeeNumber = e.employeeNumber WHERE t.comes = (SELECT MAX(dat) FROM (SELECT MAX(ti2.wDate) AS dat FROM Times ti2 WHERE ti2.employeeNumber = e.employeeNumber)) OR t.comes = NULL ORDER BY e.employeeNumber Das Problem welchem ich nun gegenüberstehe sieht folgendermaßen aus: Eigentlich soll die obige WHERE-Klausel in den Left Join da es auch sein kann dass in der Times-Tabelle noch nichts für den mitarbeiter eingetragen wurde. Wenn Ich die Abfrage so lasse wie sie jetzt ist dann sagt er dass e.employeeNumber in der 2ten SubQuery ein Parameter ohne Standardwert sei. Wenn Ich WHERE zu AND umschreibe so dass es teil des Left Joins wird, wird mir die Meldung "Fehler in Abfrageausdruck '' " (oder zumindest so ähnlich) ausgegeben. Und da sich das ganze in der WHERE-Klausel befindet werden die Mitarbeiter aus dem Ergebnis herausgenommen welche keine zeit beinhalten. Ich hatte schonmal eine Abfrage bei der das Fast funktioniert hat, allerdings war das Problem dass die letzte höchste ID von den dem mitarbeiter zugeordneten Datensätzen nicht zwangsläufig auch das höchste Datum ist (Der benutzer kann selbst Zeiten anlegen, löschen, updaten. Anlegen auch Datumstechnisch vor der letzten eintragung), und wenn es das höchste Datum ist können auch mehrere Einträge für dieses Datum vorhanden sein. meine idee war es hier dass ich zunächst das höchste Datum herausfinde und davon dann abfrage welche die höchste "comes"-zeit ist. So hätte ich auf jeden Fall die letzte eintragung. Ich benutze eine mit Delphi RadStudio XE2 erstellte Access accdb. Provider ist Jet 4.0. Ich wäre wirklich dankbar wenn ihr mir einen oder auch gerne ein paar Denkanstöße geben könntet. Greetz Shiggy Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Shiggy Geschrieben 17. September 2013 Autor Teilen Geschrieben 17. September 2013 Das goldene Bauteil um die letzte Zeit des Mitarbeiters herauszufiltern habe ich endlich. Ob es so optimal ist weiß ich nicht aber es funktioniert ^^ Jetzt muss ich es "nur" noch einbauen. SELECT DISTINCT TOP 1 wDate,comes,goes FROM Times ti WHERE ti.wDate = (SELECT MAX(ti2.wDate) FROM Times ti2 WHERE ti2.employeeNumber = 3) AND ti.employeeNumber = 3 ORDER BY ti.comes DESC Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.