Zum Inhalt springen

ACCESS Mehrfache Joins mit Begrenzung auf 1 Datensatz pro Mitarbeiter


Shiggy

Empfohlene Beiträge

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 von Shiggy
Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 von Shiggy
Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 Wochen später...

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 :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...