Requêtes SQL pour afficher uniquement les enregistrements d'achat les plus récents pour des aliments individuels

8

Je travaille avec un système d'achat / de facturation d'aliments dans MS Access 2013 et j'essaie de créer une requête SQL qui retournera le prix d'achat le plus récent pour chaque aliment individuel.

Voici un schéma des tables avec lesquelles je travaille: Tables dans la base de données MS Access

Ma compréhension de SQL est très basique, et j'ai essayé la requête (incorrecte) suivante, dans l'espoir qu'elle ne retournerait qu'un seul enregistrement par article (à cause de l' DISTINCTopérateur) et qu'elle ne retournerait que l'achat le plus récent (puisque je l'ai fait ORDER BY [Invoice Date] DESC)

SELECT DISTINCT ([Food items].Item), 
    [Food items].Item, [Food purchase data].[Price per unit], [Food purchase data].[Purchase unit], Invoices.[Invoice Date]
FROM Invoices
INNER JOIN ([Food items] 
    INNER JOIN [Food purchase data] 
    ON [Food items].ID = [Food purchase data].[Food item ID]) 
ON Invoices.ID = [Food purchase data].[Invoice ID]
ORDER BY Invoices.[Invoice Date] DESC;

Cependant, la requête ci-dessus renvoie simplement tous les achats de nourriture (c'est-à-dire plusieurs enregistrements pour chaque enregistrement [Food items]), les résultats étant triés par date. Quelqu'un peut-il m'expliquer ce que je comprends mal de l' DISTINCTopérateur? Autrement dit, pourquoi ne renvoie-t-il pas un seul enregistrement pour chaque élément dans [Food items]?

Et plus précisément - quel est le moyen le plus simple pour moi de simplement extraire les données d'achat de nourriture les plus récentes pour chaque aliment, compte tenu de la structure du tableau ci-dessus ? Je ne me soucie pas vraiment de l'efficacité autant que de la simplicité (la base de données avec laquelle je travaille est plutôt petite - il faudra des années avant qu'elle ne soit même dans les dizaines de milliers d'enregistrements). Je m'inquiète davantage que la requête soit compréhensible pour quelqu'un qui a peu de connaissances en SQL.

MISE À JOUR: J'ai donc essayé, les deux réponses suggérées ci-dessous, et aucune d'entre elles ne fonctionne (elles ne font que lancer des erreurs de syntaxe).

Sur la base des suggestions ci-dessous et de la lecture en ligne, j'ai écrit la nouvelle requête suivante, en utilisant la fonction d'agrégation max()et une GROUP BYclause:

SELECT [Food purchase data].[Food item ID], [Food purchase data].[Price per unit], max(Invoices.[Invoice Date]) AS MostRecentInvoiceDate
FROM [Food purchase data], Invoices
GROUP BY [Food purchase data].[Food item ID], [Food purchase data].[Price per unit];

Mais j'ai toujours le même problème: c'est-à-dire que je vois toujours plus d'un résultat pour chaque aliment. Quelqu'un peut-il expliquer pourquoi cette requête ne renvoie pas seulement l'achat le plus récent pour chaque aliment?

MISE À JOUR 2 (RÉSOLU!) :

Aucune des réponses ci-dessous n'a tout à fait fonctionné mais sur la base d'une modification importante de la réponse de Vladimir ci - dessous , j'ai pu créer les requêtes suivantes, qui semblent donner les bons résultats.

Tout d'abord, j'ai créé cette vue et l'ai nommée "LatestInvoices":

SELECT InvoicesMaxDate.ItemID, InvoicesMaxDate.MaxDate, InvoicesMaxDate.MaxID
FROM [Food purchase data], Invoices, (SELECT [Food purchase data].[Food item ID] AS ItemID, MAX(Invoices.[Invoice Date]) AS MaxDate, MAX(Invoices.[Invoice ID]) AS MaxID
                FROM [Food purchase data], Invoices
                WHERE Invoices.[Invoice ID] = [Food purchase data].[Invoice ID]
                GROUP BY [Food purchase data].[Food item ID]
         )  AS InvoicesMaxDate
WHERE InvoicesMaxDate.MaxID = [Food purchase data].[Invoice ID] AND
                      InvoicesMaxDate.ItemID = [Food purchase data].[Food item ID] AND 
                      InvoicesMaxDate.MaxDate = Invoices.[Invoice Date]
GROUP BY InvoicesMaxDate.ItemID, InvoicesMaxDate.MaxDate,  InvoicesMaxDate.MaxID

Ensuite, j'ai écrit une autre requête pour insérer les champs dont j'avais besoin:

SELECT [Food items].ID AS FoodItemID, [Food items].Item AS FoodItem, [Food purchase data].[Price], [Food purchase data].[Price per unit], [Food purchase data].[Purchase unit], LatestInvoices.MaxDate as InvoiceDate
FROM [Food items], [Food purchase data], LatestInvoices
WHERE LatestInvoices.[MaxID] = [Food purchase data].[Invoice ID] AND
             LatestInvoices.ItemID = [Food purchase data].[Food item ID] AND
             LatestInvoices.ItemID = [Food items].ID
ORDER BY [Food items].Item;

Merci à tous ceux qui ont pris le temps de m'aider!

J. Taylor
la source
2
DISTINCTrenvoie des lignes distinctes sur toutes les colonnes de la ligne, et non sur des colonnes uniques.
Max Vernon
2
Juste un petit conseil, évitez d'utiliser des espaces dans les noms de table et de colonne. Ensuite, vous n'aurez pas besoin de tout entourer de [et]
Max Vernon
1
Et il est (sans doute) préférable d'inclure le nom de la table dans toutes les IDcolonnes, donc IDdans la Invoicestable devient InvoiceID.
Max Vernon
Oh, cela a du sens - je pensais que DISTINCTc'était par colonnes uniques. Existe-t-il un opérateur analogue qui sélectionnera uniquement en fonction de l'unicité dans une seule colonne? Aussi, merci pour les conseils sur les conventions de dénomination - oui, c'est très ennuyeux de devoir l'utiliser [ ... ]partout ... Et je peux voir comment l'inclusion du nom de la table dans la colonne ID augmenterait la lisibilité.
J. Taylor

Réponses:

7

MS Access est plutôt limité.

Je suppose qu'il est possible d'avoir plusieurs factures pour la même date. Dans ce cas, je choisirai une facture avec l'ID le plus élevé.

Au début, nous trouverons la date de facturation maximale pour chaque aliment.

SELECT
    FPD1.[Food item ID] AS ItemID
    ,MAX(I1.[Invoice Date]) AS MaxDate
FROM
    [Food purchase data] AS FPD1
    INNER JOIN Invoices AS I1 ON I1.ID = FPD1.[Invoice ID]
GROUP BY
    FPD1.[Food item ID]

Puisqu'il est possible qu'il y ait plusieurs factures pour la date max trouvée, nous choisirons une facture avec l'ID max par article

Basé sur la syntaxe MS Access des jointures imbriquées et en utilisant cet exemple à partir des documents:

SELECT fields 
FROM 
  table1 INNER JOIN 
  (
      table2 INNER JOIN 
      (
          table3 INNER JOIN tablex ON table3.field3 = tablex.fieldx
      ) ON table2.field2 = table3.field3
  ) ON table1.field1 = table2.field2
;

Essayons de le mettre ensemble:

SELECT
    InvoicesMaxDate.ItemID
    ,InvoicesMaxDate.MaxDate
    ,MAX(I2.ID) AS MaxInvoiceID
FROM
    (
        SELECT
            FPD1.[Food item ID] AS ItemID
            ,MAX(I1.[Invoice Date]) AS MaxDate
        FROM
            [Food purchase data] AS FPD1
            INNER JOIN Invoices AS I1 ON I1.ID = FPD1.[Invoice ID]
        GROUP BY
            FPD1.[Food item ID]
    ) AS InvoicesMaxDate INNER JOIN
    (
        [Food purchase data] AS FPD2 
        INNER JOIN Invoices AS I2 ON I2.ID = FPD2.[Invoice ID]
    ) ON
        InvoicesMaxDate.ItemID = FPD2.[Food item ID] AND
        --- you may need to put extra "ON" here as well, not sure
        InvoicesMaxDate.MaxDate = I2.[Invoice Date]
GROUP BY
    InvoicesMaxDate.ItemID
    ,InvoicesMaxDate.MaxDate

Nous avons maintenant à la fois ItemID et ID de la dernière facture pour cet article. Joignez-le aux tableaux d'origine pour récupérer d'autres détails (colonnes).

SELECT
    FI3.Item
    ,FI3.Item
    ,FPD3.[Price per unit]
    ,FPD3.[Purchase unit]
    ,I3.[Invoice Date]
FROM
    (
        SELECT
            InvoicesMaxDate.ItemID
            ,InvoicesMaxDate.MaxDate
            ,MAX(I2.ID) AS MaxInvoiceID
        FROM
            (
                SELECT
                    FPD1.[Food item ID] AS ItemID
                    ,MAX(I1.[Invoice Date]) AS MaxDate
                FROM
                    [Food purchase data] AS FPD1
                    INNER JOIN Invoices AS I1 ON I1.ID = FPD1.[Invoice ID]
                GROUP BY
                    FPD1.[Food item ID]
            ) AS InvoicesMaxDate INNER JOIN
            (
                [Food purchase data] AS FPD2 
                INNER JOIN Invoices AS I2 ON I2.ID = FPD2.[Invoice ID]
            ) ON
                InvoicesMaxDate.ItemID = FPD2.[Food item ID] AND
                InvoicesMaxDate.MaxDate = I2.[Invoice Date]
        GROUP BY
            InvoicesMaxDate.ItemID
            ,InvoicesMaxDate.MaxDate
    ) AS LastInvoices INNER JOIN
    (
        [Food items] AS FI3 INNER JOIN
        (
            [Food purchase data] AS FPD3
            INNER JOIN Invoices AS I3 ON I3.ID = FPD3.[Invoice ID]
        ) ON FI3.ID = FDP3.[Food item ID]
    ) ON
        LastInvoices.MaxInvoiceID = I3.ID AND
        LastInvoices.ItemID = FI3.ID

En pratique, je créerais une vue pour la première requête avec une seule jointure. Ensuite, je créais une deuxième vue qui joint la première vue aux tables, puis la troisième vue et ainsi de suite, pour éviter les jointures imbriquées ou les minimiser. La requête globale serait plus facile à lire.


Modifiez pour clarifier ce que je veux dire en fonction de votre solution finale que vous avez mise dans la question.

Une dernière tentative pour transmettre mon message.

Voici ce que vous avez écrit sur la base de mes suggestions ci-dessus:

SELECT
    InvoicesMaxDate.ItemID
    ,InvoicesMaxDate.MaxDate
    ,Invoices.[Invoice ID]
FROM [Food purchase data], Invoices, 
    (
        SELECT 
            [Food purchase data].[Food item ID] AS ItemID
            ,MAX(Invoices.[Invoice Date]) AS MaxDate
        FROM [Food purchase data], Invoices
        WHERE Invoices.[Invoice ID] = [Food purchase data].[Invoice ID]
        GROUP BY [Food purchase data].[Food item ID]
    )  AS InvoicesMaxDate
WHERE
    Invoices.[Invoice ID] = [Food purchase data].[Invoice ID] AND
    InvoicesMaxDate.ItemID = [Food purchase data].[Food item ID] AND 
    InvoicesMaxDate.MaxDate = Invoices.[Invoice Date]
GROUP BY InvoicesMaxDate.ItemID, InvoicesMaxDate.MaxDate, Invoices.[Invoice ID];

Voici ce que je voulais dire:

SELECT
    InvoicesMaxDate.ItemID
    ,InvoicesMaxDate.MaxDate
    ,MAX(Invoices.[Invoice ID]) AS [Invoice ID]
FROM [Food purchase data], Invoices, 
    (
        SELECT
            [Food purchase data].[Food item ID] AS ItemID
            ,MAX(Invoices.[Invoice Date]) AS MaxDate
        FROM [Food purchase data], Invoices
        WHERE Invoices.[Invoice ID] = [Food purchase data].[Invoice ID]
        GROUP BY [Food purchase data].[Food item ID]
    )  AS InvoicesMaxDate
WHERE
    Invoices.[Invoice ID] = [Food purchase data].[Invoice ID] AND
    InvoicesMaxDate.ItemID = [Food purchase data].[Food item ID] AND 
    InvoicesMaxDate.MaxDate = Invoices.[Invoice Date]
GROUP BY InvoicesMaxDate.ItemID, InvoicesMaxDate.MaxDate;

Voyez-vous la différence?

Le InvoicesMaxDateretourne MAX Invoice Datepour chacun Food item ID. S'il y a deux factures pour le même Food item IDavec le même MAX, Invoice Datenous devons choisir une facture parmi elles. Cela se fait en regroupant par InvoicesMaxDate.ItemID, InvoicesMaxDate.MaxDate. Il ne devrait pas y avoir de regroupement Invoices.[Invoice ID]ici, car nous voulons sélectionner la facture avec l'ID maximum.

Une fois que vous avez enregistré cette requête en tant que LatestInvoicesvue, elle est utilisée plus loin comme vous l'avez correctement écrit (notez que la requête finale utilise LatestInvoices.[Invoice ID]et LatestInvoices.ItemID, mais n'utilise pas LatestInvoices.MaxDate):

SELECT 
    [Food items].ID as FoodItemID
    ,[Food items].Item as FoodItem
    ,[Food purchase data].[Price]
    ,[Food purchase data].[Price per unit]
    ,[Food purchase data].[Purchase unit]
    ,Invoices.[Invoice Date]
FROM [Food items], [Food purchase data], Invoices, LatestInvoices
WHERE 
    Invoices.[Invoice ID] = [Food purchase data].[Invoice ID] AND
    [Food items].ID = [Food purchase data].[Food item ID] AND
    LatestInvoices.[Invoice ID] = Invoices.[Invoice ID] AND 
    LatestInvoices.ItemID = [Food items].ID
ORDER BY [Food items].Item

Quant à, pourquoi votre dernière requête dans la question renvoie plusieurs lignes par article:

SELECT 
    [Food purchase data].[Food item ID]
    , [Food purchase data].[Price per unit]
    , max(Invoices.[Invoice Date]) AS MostRecentInvoiceDate
FROM [Food purchase data], Invoices
GROUP BY [Food purchase data].[Food item ID], [Food purchase data].[Price per unit];

Vous regroupez ici par [Food item ID]et [Price per unit], vous obtiendrez donc autant de lignes qu'il y a de combinaisons uniques de ces deux colonnes.

La requête suivante retournerait une ligne par [Food item ID].

SELECT 
    [Food purchase data].[Food item ID]
    , max(Invoices.[Invoice Date]) AS MostRecentInvoiceDate
FROM [Food purchase data], Invoices
GROUP BY [Food purchase data].[Food item ID];

Une remarque, vous devriez vraiment utiliser explicite INNER JOINau lieu de ,. Cette syntaxe a 20 ans.

SELECT 
    [Food purchase data].[Food item ID]
    , max(Invoices.[Invoice Date]) AS MostRecentInvoiceDate
FROM
    [Food purchase data]
    INNER JOIN Invoices ON Invoices.ID = [Food purchase data].[Invoice ID]
GROUP BY [Food purchase data].[Food item ID];
Vladimir Baranov
la source
Merci pour votre réponse très détaillée! La première requête que vous avez partagée a fonctionné et a effectivement extrait la date de facturation la plus récente pour chaque aliment, ce qui est vraiment utile. Cependant, quand j'ai essayé les 2 prochaines requêtes que vous avez partagées, j'ai eu "Syntax error (missing operator) in query expression"l'expression INNER JOIN Invoices AS I2 ON I2.ID = FPD2.[Invoice ID]... Je vais jouer avec elle plus pour voir si je peux la faire fonctionner.
J. Taylor
@JesseTaylor, apparemment, il est nécessaire de mettre explicitement des crochets (et )lorsque la requête utilise plusieurs jointures et de déplacer ONun peu la clause. Je n'ai pas accès à vérifier, mais je peux essayer de deviner la syntaxe correcte en lisant les documents plus tard dans la journée.
Vladimir Baranov
@JesseTaylor, j'ai mis à jour la réponse et j'espère que je devine la syntaxe correctement. Veuillez l'essayer et faites-moi savoir si cela fonctionne.
Vladimir Baranov
1
@JesseTaylor, vous êtes les bienvenus. Cela fait un moment que je n'ai pas utilisé Access et il est difficile de trouver la bonne syntaxe. Une remarque sur votre point de vue LatestInvoices: la finale GROUPne devrait être BY InvoicesMaxDate.ItemID, InvoicesMaxDate.MaxDateque, sans Invoices.[Invoice ID]. Dans la SELECTpartie il devrait y en avoir MAX(Invoices.[Invoice ID]) AS [Invoice ID]. C'est tout l'intérêt. Au début (dans la requête interne), nous GROUP BY [Food item ID]trouvons la date de facturation maximale. Il peut y avoir plusieurs factures avec cette date, il y a donc une seconde GROUP BYpour choisir la facture avec un ID maximum parmi elles.
Vladimir Baranov du
1
@JesseTaylor, Malheureusement, vous m'avez mal compris. J'ai mis à jour ma réponse pour vous montrer ce que je voulais dire. Pour voir la différence, ajoutez deux factures à vos (échantillons) données pour la même ItemIDavec la même grande date et essayez les deux requêtes.
Vladimir Baranov
3

Une requête qui fonctionne juste hors de la boîte:

SELECT Fi.Item, Fpd.[Price per unit], Fpd.[Purchase unit]
FROM [Food items] Fi INNER JOIN [Food purchase data] Fpd
ON Fpd.[Food item ID] = Fi.ID
WHERE Fpd.[Invoice ID] = (
  SELECT TOP 1 I.ID 
  FROM Invoices I INNER JOIN [Food purchase data] Fpd2
  ON Fpd2.[Invoice ID] = I.ID
  WHERE Fpd2.[Food item ID] = Fpd.[Food item ID]
  ORDER BY I.[Invoice Date] DESC
)
aksenoff
la source
Lorsque j'exécute cette requête, j'obtiens simplement une erreur: "Tout au plus un enregistrement peut être renvoyé par cette sous-requête." La vue de la feuille de données montre juste un enregistrement avec "#NAME?" dans tous les domaines.
J. Taylor
3

Je pourrais le résoudre avec la requête suivante:

Select MAX(AllItemBuyings.[invoice date]) as RecentBuyingDate, AllItemBuyings.[Food Item Id]  From 
(    
    select fpd.[Invoice Id], fpd.[Food Item Id], I.[invoice date] From [Food purchase data]as fpd 
    inner join invoices I on fpd.[Invoice Id] = I.ID

) as AllItemBuyings    
Group By AllItemBuyings.[Food Item Id]

Parce que je n'ai pas d'accès, j'ai testé cela sur SQL Server. J'espère que cela fonctionnera pour vous.

Modifier / Requête supplémentaire : Afin d'ajouter les autres colonnes du tableau des aliments, j'ai modifié la requête. Je l'ai fait d'une manière que je n'aime pas vraiment. Si cela vous convient, cela dépend de vos données et de vos besoins. J'ai de nouveau rejoint la table INVOICES en utilisant la date de commande. Dans le cas où il s'agit d'une date, y compris l'heure de mon travail, veuillez en être conscient. Je ne vois pas d'autre moyen dans votre scénario. Peut-être existe-t-il une meilleure solution en utilisant la requête récursive ...?

Veuillez essayer et faites-moi savoir si cela fonctionne:

Select Recents.RecentBuyingDate, pd.* From 
(

   Select MAX(AllItemBuyings.[invoice date]) as RecentBuyingDate, AllItemBuyings.[Food Item Id]    From 
    (    
        select fpd.[Invoice Id], fpd.[Food Item Id], I.[invoice date], fpd.ID From [Food purchase data]as fpd 
        inner join invoices I on fpd.[Invoice Id] = I.ID

    ) as AllItemBuyings    
    Group By AllItemBuyings.[Food Item Id]

    ) as Recents    
    Join Invoices i on i.[invoice date] = Recents.RecentBuyingDate
    Join [Food purchase data] pd ON pd.[Invoice Id] = i.ID AND pd.[Food Item Id] = Recents.[Food Item Id]
Magier
la source
Je vous remercie. Cela me donne correctement la date d'achat la plus récente pour chaque article. Comment puis-je utiliser cela, cependant, à tirer dans tous les domaines que je l' ai mentionné dans la question (par exemple Item, Price per unitetc.)?
J. Taylor
La nouvelle requête que vous avez suggérée génère simplement un message d'erreur qui ne dit rien d'autre que "Erreur de syntaxe dans la clause FROM".
J. Taylor
Access nécessite peut-être que l'opération JOIN soit exactement "INNER JOIN". Essayez INNSER JOIN au lieu de simplement JOIN.
Magier
2

Je crois que ce qui suit devrait fonctionner.

SELECT fi.[Item], fd.[Price per unit], MAX(i.[Invoice Date])
FROM [Invoices] AS i
INNER JOIN [Food Purchase Data] AS fd
    ON i.ID = fd.[Invoice ID]
INNER JOIN [Food items] AS fi
    ON fd.[Food item ID] = fi.ID
GROUP BY fi.Item, fd.[Price per unit]
ORDER BY i.[Invoice Date] DESC

Quant à savoir pourquoi votre requête ne renvoie pas les résultats que vous souhaitez:

SELECT [Food purchase data].[Food item ID], [Food purchase data].[Price per unit], max(Invoices.[Invoice Date]) AS MostRecentInvoiceDate
FROM [Food purchase data], Invoices
GROUP BY [Food purchase data].[Food item ID], [Food purchase data].[Price per unit];

Le plus gros problème que je vois est que vous ne faites rien pour rejoindre vos tables. La "jointure" implicite qui est présente en listant simplement les deux dans votre clause FROM vous donne un produit cartésien. Fondamentalement, il renverra toutes les combinaisons possibles dans votre base de données pour les champs que vous interrogez.

Par exemple, si les deux tables ont chacune 3 enregistrements au lieu de renvoyer la date la plus récente, votre requête renvoie quelque chose comme: 1,1 1,2 1,3 2,1 2,2 2,3 3,1 3,2 3 , 3

Il est très important que vous déclariez explicitement vos jointures. Vous pouvez le faire de deux manières dans votre requête:

FROM [Food purchase data] AS fd, [Invoices] AS i
WHERE fd.[Invoice ID] = i.[ID]

OU

FROM [Food purchase data] AS fd
INNER JOIN [Invoices] AS i
    ON fd.[Invoice ID] = i.[ID]

Requêtes mises à jour, si celles-ci ne fonctionnent toujours pas, essayez de supprimer les alias et d'utiliser les noms de colonne complets.

agpoweredmg
la source
Continuons cette discussion dans le chat .
agpoweredmg
0

Je suis d'accord avec les suggestions de Max concernant votre modèle de données. Leur mise en œuvre rendra votre SQL plus lisible à long terme.

Cela dit, DISTINCT affichera des lignes uniques. Donc, pour ne montrer que les plus récents, vous devez limiter les colonnes affichées.

Essayez quelque chose comme:

SELECT [Food purchase data].[Food item ID], max(Invoices.[Invoice Date]) AS MostRecentInvoiceDate
FROM Invoices 
INNER JOIN ([Food items] ON [Food items].ID = [Food purchase data].[Food item ID]) 
GROUP BY [Food purchase data].[Food item ID]

(Traduction: pour chaque article du magasin, affichez sa date de facture la plus récente.)

Vous pouvez l'enregistrer en tant que vue et l'utiliser dans une autre requête comme vous le feriez pour une table. Vous pouvez donc faire une jointure interne sur la facture pour le prix d'achat et les jointures sur les autres tables si vous avez besoin de ces détails.

(Théoriquement, vous pouvez également effectuer une requête imbriquée, mais comme vous avez demandé une requête simple, une requête enregistrée est plus simple.)

MISE À JOUR en fonction de votre mise à jour:

Je vais utiliser des clauses WHERE au lieu de JOINS car je n'ai pas MS Access à portée de main. Vous devez pouvoir utiliser l'interface graphique pour établir les connexions entre les tables dans MS Access en fonction de ces informations. (Veuillez fournir un SQLFiddle si vous avez vraiment besoin d'aide pour un dépannage supplémentaire.)

Étape 1: enregistrer ceci en tant que VUE (par exemple, "MostRecentInvoice")

SELECT [Food purchase data].[Food item ID] AS FoodItemID, max(Invoices.[Invoice Date]) AS MostRecentInvoiceDate
FROM [Food purchase data], Invoices
WHERE [Food purchase data].[Food item ID] = Invoices.ID
GROUP BY [Food purchase data].[Food item ID];

Étape 2: utiliser la vue dans une 2e requête

SELECT (list all the fields you need here)
FROM MostRecentInvoice, Invoices, etc...
WHERE MostRecentInvoice.FoodItemID = [Food purchase data].[Food item ID] 
AND MostRecentInvoice.MostRecentInvoiceDate = Invoices.[Invoice Date]
AND (whatever else joins you'll need for the other tables)

... et pour répondre à votre question: La 2e requête de la mise à jour ne fonctionne pas car la colonne [Prix par unité] se trouve dans vos instructions SELECT et GROUP BY. Cela signifie essentiellement que vous demandez à voir TOUTES les valeurs possibles de [Prix par unité] même si ce que vous voulez vraiment n'est qu'une seule: la valeur la plus récente.

chabzjo
la source
Merci, mais lorsque j'essaie d'exécuter la requête que vous avez partagée, j'obtiens simplement une erreur: "Erreur de syntaxe dans l'opération JOIN".
J. Taylor
Désolé, je n'ai pas eu le temps de créer moi-même les tables dans Access. J'ai supposé que vous aviez un peu d'expérience avec les jointures puisqu'il y en avait dans votre question. Avez-vous essayé de le créer en faisant Créer -> Requête dans Access?
chabzjo
La première requête que vous avez partagée ne donne pas de résultats corrects à cause de la ligne WHERE [Food purchase data].[Food item ID] = Invoices.ID... Je suppose que vous vouliez dire WHERE [Food purchase data].[Invoice ID] = Invoices.[Invoice ID]mais cela renvoie toujours plusieurs dates par aliment au lieu de la plus récente.
J. Taylor