Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

Verschachtelte INNER JOINS in Access

Begonnen von Georg_, Januar 16, 2017, 10:23:29

⏪ vorheriges - nächstes ⏩

Georg_

Guten Morgen Forum,
danke für die freundliche Aufnahme.
Gestern habe ich den ganzen Tag mit einer Abfrage gerungen. Am Ende habe ich zwar eine Lösung gefunden, diese befriedigt mich aber nicht, weil ich denke, dass es auch anders gehen müsste.
Es geht um zwei Tabellen, die in einer 1:n-Beziehung zueinander stehen. Die Abfrage soll mir zu jedem Datensatz der 1-Tabelle einige Felder aus dem Datensatz der n-Tabelle holen, in dem die jüngste Frist steht, also quasi den letzten Eintrag. Dann soll noch eine Spalte dazugefügt werden, die das Datum des ersten Eintrags enthält.
Meiner Meinung nach sollte das mit einem verschachtelten JOIN für die Frist funktionieren. Meine Syntax liefert aber den Fehler: Syntaxfehler in JOIN-Operation. Den Fehler konnte ich trotz stundenlanger Suche nicht finden. Hier ist die Syntax der Abfrage:

SELECT A.VorgangID, A.refMandant, A.refFallTyp, A.refSachbearbeiter,
B.refAStelle, B.Aktenzeichen, B.refVorgangTyp, B.Frist, F.AnfrageDatum
FROM tblVorgaenge as A
INNER JOIN (tblAStelleLog as B
INNER JOIN (SELECT C.refVorgang, Max(C.Frist ) as AktFrist
FROM tblAStelleLog AS C
GROUP BY C.refVorgang) AS D
ON D.refVorgang = B.refVorgang
WHERE D.AktFrist = B.Frist)
INNER JOIN (SELECT E.refVorgang, MIN(E.ADatum) AS AnfrageDatum
FROM tblAStelleLog as E
GROUP BY E.refVorgang) AS F
ON F.refVorgang = B.refVorgang
ON B.refVorgang = A.VorgangID;


Wie gesagt habe ich am Ende eine funktionierende Lösung gefunden, indem ich den äußeren JOIN durch einen Komma-JOIN ersetzt habe:

SELECT A.VorgangID, A.refMandant, A.refFallTyp, A.refSachbearbeiter,
B.refAStelle, B.Aktenzeichen, B.refVorgangTyp, B.Frist, F.AnfrageDatum
FROM tblVorgaenge as A, (tblAStelleLog as B
INNER JOIN (SELECT C.refVorgang, MAX(C.Frist) AS AktFrist
FROM tblAStelleLog AS C
GROUP BY C.refVorgang) AS D
ON D.refVorgang = B.refVorgang)
INNER JOIN (SELECT E.refVorgang, MIN(E.ADatum) AS AnfrageDatum
FROM tblAStelleLog as E
GROUP BY E.refVorgang) AS F
ON F.refVorgang = B.refVorgang
WHERE (D.AktFrist = B.Frist) AND (A.VorgangID = B.refVorgang)
ORDER BY A.VorgangID;


Es wurmt mich unheimlich, dass ich partout nicht herausfinden kann, warum die Version mit den verschachtelten JOINs nicht funktioniert. Ich kann einfach nicht glauben, dass Access hier die Flügel streckt und denke, der Fehler liegt in der Syntax.
Könnt Ihr mir helfen?

Georg

ebs17

Ich denke, Frist und Annahmedatum kannst Du in einem Schritt ermitteln:
SELECT
   refVorgang,
   MAX(Frist) AS AktFrist,
   MIN(ADatum) AS AnfrageDatum
FROM
   tblAStelleLog
GROUP BY
   refVorgang


Jetzt kannst Du tblAStelleLog  für die weiteren Felder hinzuverknüpfen, wie dann auch tblVorgaenge.
Mit freundlichem Glück Auf!

Eberhard

Georg_

Hallo Eberhard,
das geht m.E. leider nicht, weil das AnfrageDatum in einem anderen Datensatz steht.
Das ist aber auch nicht mein Problem. Das Konstrukt
...
FROM tblVorgaenge as A
INNER JOIN (tblAStelleLog as B
INNER JOIN (
SELECT C.refVorgang, ...


wird von Access als fehlerhaft bemängelt und ich weiß nicht, ob ich eine Klammer falsch gesetzt habe o.ä. oder ob Access das einfach nicht verarbeiten kann.

Georg

ebs17

Zitatweil das AnfrageDatum in einem anderen Datensatz steht
Ich würde behaupten, dass beim Aggregieren die entsprechenden Min-/Max-Werte aus der Gruppe ermittelt werden, nicht Datensätze, in denen das eine oder andere steht.

Zu Deiner Abfrage: Zu komplex ist das noch nicht für Jet, daher würde ich wie vermutet auf die Klammersetzung tippen. Zur Auflösung würde ich den FROM-Teil der Abfrage schrittweise noch einmal neu zusammensetzen
Mit freundlichem Glück Auf!

Eberhard

Georg_

Hallo Eberhard,
danke für den Tip, die beiden Aggregate können tatsächlich in einem Zug abgefragt werden. Wieder was gelernt.
Bzgl. der Syntax habe ich nicht viel Hoffnung, s.o.

Georg

Georg_

Hallo mal wieder,
ich habe meine Abfrage inzwischen hinbekommen:
    strSQL = "SELECT A.refVorgang, A.refAStelle, A.refAStelleKontakt, A.refVorgangTyp, A.Aktenzeichen, A.Frist, E.AnfrageDatum " & _
                "FROM (tblAStelleLog AS A " & _
                    "INNER JOIN (SELECT B.refVorgang, MAX(B.Frist) AS MaxFrist " & _
                                    "FROM tblAStelleLog AS B " & _
                                    "GROUP BY B.refVorgang) AS C " & _
                    "ON A.refVorgang = C.refVorgang) " & _
                    "INNER JOIN (SELECT D.refVorgang, MIN(D.ADatum) AS AnfrageDatum " & _
                                    "FROM tblAStelleLog AS D " & _
                                    "GROUP BY D.refVorgang) AS E " & _
                    "ON A.refVorgang = E.refVorgang " & _
                "WHERE ((C.MaxFrist = A.Frist));"

(Die Tags funktionieren nicht, müssen von Hand eingefügt werden)

Etwas anders als zuerst gedacht, aber liefert genau das gewünschte Ergebnis.

Georg