3 votes

MS Access - Requête groupée basée sur le champ MAX

J'essaie de construire une requête SQL qui prend les données suivantes :

+-------------+--------+---------+---------+--------+
| 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     |
+-------------+--------+---------+---------+--------+

Et renvoie l'ID de la dernière version et ses données correspondantes, où les critères de Fruit est examiné.

Une chaîne SQL serait nécessaire pour retourner l'ID avec la classe pour la version Max où Fruit = No

Résultats :

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

J'ai seulement besoin de retourner l'ID et sa classe pour les stocker dans une boîte de liste MS Access.

J'ai réussi à construire une requête Group By / Max dans l'éditeur et je n'ai pu obtenir que le retour des ID groupés, mais les données correspondantes n'étaient pas associées à la version maximale.

Merci pour votre aide et votre expertise.

0voto

Lee Mac Points 847

Il existe plusieurs façons d'y parvenir.

Les exemples suivants supposent tous que votre table est nommée table1 et que vos champs sont id , class , version y fruit (pas fruit? ) - modifiez-les comme il convient en fonction de vos données.

Note : les exemples suivants supposent que votre fruit Le champ est un texte champ. Si votre fruit est en fait un booléen (oui/non) puis supprimez les guillemets simples autour de 'No' dans les exemples suivants.


Utilisation d'une sous-requête jointe :

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

Ici, la sous-requête sélectionne la plus grande version pour chaque id pour les dossiers où fruit = 'No' et celle-ci est ensuite jointe à l'ensemble des données afin de renvoyer les champs requis pour chacun des éléments suivants id y version .


Utilisation d'une sous-requête corrélée :

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)

Ici, la sélection est effectuée entièrement au sein de l WHERE qui, pour chaque enregistrement, vérifie s'il existe un autre enregistrement dans l'ensemble avec le même nom. id et une plus grande version et si c'est le cas, l'enregistrement n'est pas renvoyé.


Utilisation d'un LEFT JOIN avec des critères de jonction inégaux :

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

Cet exemple ne peut être représenté dans MS Access que dans la vue SQL, car le Query Designer de MS Access ne peut pas afficher les jointures qui ont des critères de jointure égaux (c'est-à-dire où un champ est égal à un autre).

Le fonctionnement de cet exemple est similaire à celui de la sous-requête corrélée, mais la sélection est effectuée par la jointure, plutôt qu'à l'intérieur de la balise WHERE clause.


Enfin, notez que le résultat de votre exemple est incorrect : le class pour le maximum version para id = 'Onion' devrait être WEST , nicht NORTH .

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X