MS Access - Gruppierte Abfrage basierend auf dem MAX-Feld

935
ExcelMania

Ich versuche, eine SQL-Abfrage zu erstellen, die die folgenden Daten enthält:

+-------------+--------+---------+---------+--------+ | Primary Key | ID | Version | Class | Fruit? | +-------------+--------+---------+---------+--------+ | 1 | Banana | 1 | NORTH | Yes | | 2 | Onion | 1 | WEST | No | | 3 | Orange | 1 | NA | Yes | | 4 | Orange | 2 | PACIFIC | Yes | | 5 | Banana | 2 | EUR | Yes | | 6 | Celery | 1 | EUR | No | | 7 | Celery | 3 | SOUTH | No | | 8 | Celery | 4 | SOUTH | No | | 9 | Pepper | 1 | N-PAC | No | | 10 | Pepper | 2 | N-PAX | No | +-------------+--------+---------+---------+--------+ 

Und gibt die ID der neuesten Version und die entsprechenden Daten zurück, bei denen die Kriterien von Fruitgeprüft werden.

Ein SQL-String würde benötigt, um die ID mit der Klasse für die Max-Version wo zurückzugeben Fruit = No

Ergebnisse:

+--------+-------+ | ID | Class | +--------+-------+ | Onion | NORTH | | Celery | SOUTH | | Pepper | N-PAX | +--------+-------+ 

Ich muss nur die ID und ihre Klasse zurückgeben, um sie in einem MS Access-Listenfeld zu speichern.

Ich habe es geschafft, eine Group By / Max-Abfrage im Editor zu erstellen und konnte nur IDs zur Gruppierung zurückgeben, aber die entsprechenden Daten waren nicht mit der maximalen Version verknüpft.

Vielen Dank für Ihre Hilfe und Ihr Fachwissen.

3

1 Antwort auf die Frage

0
Lee Mac

Es gibt mehrere Möglichkeiten, dies zu erreichen.

Die folgenden Beispiele gehen alle davon aus, dass Ihre Tabelle mit dem Namen ist table1und dass Ihre Felder sind id, class, versionund fruit(nicht fruit?) - diese gegebenenfalls ändern, um Ihre Daten zu entsprechen.

Hinweis: In den folgenden Beispielen wird davon ausgegangen, dass Ihr fruitFeld ein Textfeld ist. Wenn es sich bei Ihrem fruitFeld tatsächlich um ein boolesches Feld (Ja / Nein) handelt, entfernen Sie 'No'in den folgenden Beispielen die einfachen Anführungszeichen .


Verwenden einer verbundenen Unterabfrage:

select u.id, u.class from table1 u inner join ( select t.id, max(t.version) as mv from table1 t where t.fruit = 'No' group by t.id ) v on u.id = v.id and u.version = v.mv 

Hier wählt die Unterabfrage jeweils die größte versionfür idDatensätze aus, wobei fruit = 'No'diese mit dem vollständigen Datensatz verbunden wird, um die erforderlichen Felder für jedes idund zurückzugeben version.


Verwenden einer korrelierten Unterabfrage:

select t.id, t.class from table1 t where t.fruit = 'No' and not exists (select 1 from table1 u where u.id = t.id and u.fruit = 'No' and u.version > t.version) 

Hier wird die Auswahl vollständig innerhalb der WHEREKlausel durchgeführt, die für jeden Datensatz prüft, ob ein weiterer Datensatz im Satz mit demselben idund einem größeren versionDatensatz vorhanden ist. Wenn ja, wird der Datensatz nicht zurückgegeben.


Verwenden eines LEFT JOINmit ungleichen Join-Kriterien:

select t.id, t.class from table1 t left join table1 u on t.id = u.id and t.version < u.version where t.fruit = 'No' and u.id is null 

Dieses Beispiel kann nur in MS Access in der SQL-Ansicht dargestellt werden, da der MS Access-Abfrage-Designer keine Verknüpfungen anzeigen kann, die gleiche Verknüpfungskriterien haben (dh, wenn ein Feld einem anderen entspricht).

Dieses Beispiel ähnelt im Betrieb der korrelierten Unterabfrage, die Auswahl wird jedoch vom Join und nicht innerhalb der WHEREKlausel ausgeführt.


Beachten Sie schließlich, dass das angegebene Beispielergebnis falsch ist: classDas Maximum versionfür for id = 'Onion'sollte WESTnicht sein SOUTH.