1.
free
17.02.2010 19:25:58 Peter de Maas Lesen/Editieren
Antworten Auswahlabfrage mit gleichen Datumswerten Hallo, ich habe mal wieder ein SQl Problem (SQL/Access/VB), bei dem ich überhaupt trotz verschiedener Ideen den Wald vor lauter Bäumen nicht sehe und wo ich nochmal um Hilfe bitten möchte. Es geht um eine Abfrage, die eigentlich sehr simpel ist, bzw mir schien. Ausgehend von einer Tabelle, die aus einer Personenid (idd), eine Datensatz id (id) ein DatensatzDAtum (jourdat) und weitere Statusfelder (akt, wer, status...) für jeden Datensatz enthält. Die id ist jeweils natürlich einamlig, es gibt aber jede Menge Datensätze mit gleichen idd (da es sich um zuordnungen zu bestimmten Personen handelt) und diese sind teilweise auch mit gleichem Datum versehen (da Einträge am gleichen Tag gemacht wurden). Tabelle könnte dann so aussehen:
idd id jourdat akt stat weiterefelder ... 173 397 05.06.2008 3 2 ... 173 456 05.06.2008 2 5 ... 174 134 01.03.2007 4 3 ... ... Aufgabe meiner Abfrage ist es nun, jeweil die zeile jeder vertretenen idd (Person) herauszufiltern, die in erster linie das höchste Datum innerhalb der Gruppe der idd hat und in zweiter linie, wenn das höchste Datum mehrfach vertreten ist, die höchste id innerhalb der gleichen DatumsDatensätze einer idd. Hintergrund ist, dass es sich dabei um Journaleinträge handelt und zur weitern Verarbeitung soll eine Tabelle zusammengestellt werden, bei der zu jeder Person der zeitlich und (2.) id-mäßig höchste Eintrag Informationen enthält, die weiterverwertet werden sollen.
Ich bin nun soweit, folgende Lösung nachvollziehen zu können, die aber leider einige wenige Datensätze "vergisst", vermutlich, weil in diesen mehrere gleiche "DAtumsdatensätze" vorkommen (T2 ist die Basistabelle): SELECT * FROM (SELECT * FROM T2 WHERE T2.jourdat IN (SELECT MAX(T2.jourdat) As MAXIMAL FROM T2 GROUP BY T2.idd))WHERE T2.ID IN (SELECT Max(T2.ID) AS HoheID FROM T2 GROUP BY T2.idd)
Können Sie mir da wohl noch mal einen "Denkanstoss" - möglichst einen kräftigen ;-) - in die richtige Richtung geben?
In jedem Fall schon einmal vielen Dank,
Peter 2.
free
18.02.2010 15:08:15 Jürgen Auer Lesen/Editieren
Antworten Re: Auswahlabfrage mit gleichen Datumswerten Das
SELECT MAX(T2.jourdat) As MAXIMAL FROM T2 GROUP BY T2.idd
als Unterabfrage bringt überhaupt nichts, wenn die idd nicht mit ausgegeben wird.
Umgekehrt ist das fast schon die Lösung:
Select B.idd, Max(B.id) As id From T2 As B Group By B.idd
liefert zu jeder idd die maximale id.
Das per Join kombiniert liefert die Details:
Select A.id, A.idd, A.jourdat, A.andere Spalten From T2 As A Inner Join (Select B.idd, Max(B.id) As id From T2 As B Group By B.idd) As B1 On A.id = B.id
3.
free
18.02.2010 20:14:44 Peter de Maas Lesen/Editieren
Antworten Re:Auswahlabfrage mit gleichen Datumswerten Vielen Dank für den Lösungsweg. Ich übertrage die SQLAbfrage in Access und kann das Ergebnis mit einer Referenz vergleichen. Zunächst wirft mir Access eine Fehlermeldung aus: "Syntaxfehler in Join-Operation". Ändere ich die Group by Klausel zu "Group By B.idd) As B", dann wird die korrekte Anzahl Datensätze ausgeworfen. Ein Vergleich mit der Basistabelle T2 zeigt aber einen Fehler, der immer dann auftritt, wenn innerhalb einer idd-Gruppe der zeitlich höchste Datensatz nicht auch die höchste id hat, wie z.b. so:
T2 ... idd ID jourdat ... 180 3377 02.04.2009 180 3445 06.04.2009 180 4399 27.04.2009 180 4398 08.06.2009 ...
Die Lösungsabfrage wirft für diese Gruppe den Datensatz mit der id 4399 aus, der mit der id 4398 wäre aber der richtige.
Oder habe ich die Gruppierungsfunktion/vermeindlicher Fehler mit "B1" missverstanden?
Grüße Peter 4.
free
18.02.2010 21:32:22 Jürgen Auer Lesen/Editieren
Antworten Re:Auswahlabfrage mit gleichen Datumswerten Wenn dieser Fall auftritt (höhere ID, aber älteres Datum), dann nimmt man eben das Datums-Maximum und muß dann nur beim Inner Join doppelt verknüpfen:
Select A.id, A.idd, A.jourdat, A.andere Spalten From T2 As A Inner Join (Select B.idd, Max(B.jourdat) As max_jourdat From T2 As B Group By B.idd) As B1 On A.idd = B1.idd And A.jourdat = B1.jourdat
Denn dann ist die Kombination aus idd und Max(jourdat) über diese idd immer eindeutig, also wird zu jeder Zeile aus A höchstens eine Zeile in der Unterabfrage gefunden. 5.
free
19.02.2010 00:11:37 Peter de Maas Lesen/Editieren
Antworten Re:Auswahlabfrage mit gleichen Datumswerten Mühsam ernährt sich das Eichhörnchen. Aber ich glaube, dass ich die Funktionsweise der Abfrage jetzt verstehe. Umso mehr verstehe ich nicht, wieso beim Versuch sie in Access anzuwenden, dieses nach einer Parametereingabe für B1.jourdat verlangt? Genau der wird doch angeboten? Ich bekomme die Abfrage jedenfalls nicht ans rennen. Gruß Peter 6.
free
19.02.2010 10:50:32 Jürgen Auer Lesen/Editieren
Antworten Re: Auswahlabfrage mit gleichen Datumswerten > Umso mehr verstehe ich nicht, wieso beim Versuch sie in Access anzuwenden, dieses nach einer Parametereingabe für B1.jourdat verlangt? Genau der wird doch angeboten?
Weil ich mich verschrieben hatte.
Das Maximum in der Unterabfrage wird als 'max_jourdat' ausgegeben, also muß das auch so in der äußeren Join-Verknüpfung genutzt werden. 7.
free
19.02.2010 16:45:37 Peter de Maas Lesen/Editieren
Antworten Re:Auswahlabfrage mit gleichen Datumswerten > also muß das auch so in der äußeren Join-Verknüpfung genutzt werden.
wenn ich B1.max_jourdat einsetze, erhalte ich aber wieder mehrere gleiche Idds und zwar da, wo das Datum auch bei den iDDs identisch ist. 8.
free
19.02.2010 17:44:53 Jürgen Auer Lesen/Editieren
Antworten Re: Auswahlabfrage mit gleichen Datumswerten > wenn ich B1.max_jourdat einsetze, erhalte ich aber wieder mehrere gleiche Idds und zwar da, wo das Datum auch bei den iDDs identisch ist.
Eigentlich ist dann das Design falsch. Ich dachte, das sei ein DateTime-Feld, das eindeutig wäre.
In dem Fall muß man die Unterabfrage, die einem idd und maximales Datum zurückgibt, zunächst mit der Gesamttabelle per Join verknüpfen und die maximale ID zu jeder Kombination aus idd / Datum ermitteln. Also die letzte Abfrage, aber nur mit drei Ausgabespalten Max(id), idd und Datum, gruppiert nach idd / Datum.
Und dann das wiederum als Unterabfrage nehmen, um über eine Verknüpfung über die id die restlichen Spalten zu ermitteln. 9.
free
19.02.2010 18:42:58 Peter de Maas Lesen/Editieren
Antworten Re:Auswahlabfrage mit gleichen Datumswerten Langsam! Ich versteh wie es gemeint ist, kann es aber nicht umsetzen. Um mich dem dennoch anzunähern, schau ich mir das Ergebnis der bestehenden Abfrage an und das ists ja schon fast, wenn ich mich nicht täusche, bzw. die Zieltabelle ist darin. Die mehrfacheinträge sind ja allesammt richtig in bezug aufs DAtum, es müsste nur aus jeder mehrfach idd die herausgefiltert werden, mit der höchsten id. Das krieg ich ja noch hin und das sieht dann so aus:
SELECT A.idd, Max(A.ID) AS MaxvonID, A.jourdat FROM T2 AS A INNER JOIN [Select B.idd, Max(B.jourdat) As max_jourdat From T2 As B Group By B.idd]. AS B1 ON (A.idd = B1.idd) AND (A.jourdat = B1.max_jourdat) GROUP BY A.idd, A.jourdat;
Aber es hört dann auf, wenn ich jetzt...
> Und dann das wiederum als Unterabfrage nehmen, um über eine Verknüpfung über die id die restlichen Spalten zu ermitteln.
... also genau die anderen Spalten hinzunehmen will?
(und anfangs hatte ich wirklich gedacht, das sei eine ganz simple Aufgabenstellung). 10.
free
19.02.2010 19:45:13 Peter de Maas Lesen/Editieren
Antworten Re:Auswahlabfrage mit gleichen Datumswerten Ich glaub ich habs doch. Vielleicht noch die Frage an den Profi: geht das auch noch etwas eleganter? Oder ists wirklich die perfekte Abfrage?
SELECT T2.* FROM T2 WHERE (((T2.ID) In (SELECT Max(A.ID) AS MaxvonID FROM T2 AS A INNER JOIN [Select B.idd, Max(B.jourdat) As max_jourdat From T2 As B Group By B.idd]. AS B1 ON (A.jourdat = B1.max_jourdat) AND (A.idd = B1.idd) GROUP BY A.idd, A.jourdat )));
Auf jeden Fall, vielen Dank für die Hilfe!!!! Peter 11.
free
20.02.2010 19:29:53 Jürgen Auer Lesen/Editieren
Antworten Re: Auswahlabfrage mit gleichen Datumswerten Im Prinzip ist das die Lösung, wenn das Datumsfeld nur den Tag enthält, also nicht eindeutig ist.
Ich nutze zwar oft eher die Variante mit einem Inner Join, aber das dürfte kaum einen Unterschied machen bzw. auf dem MS-SqlServer womöglich sogar dieselben Abfragepläne generieren.
Also
Select C1.* From T2 As C1 Inner Join (gesamte obige Unterabfrage) As C2 On C1.id = C2.MaxvonID
Die eckigen Klammern sind Access-typisch, auf dem MS-SqlServer sind das runde Klammern.