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:
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' DISTINCT
opé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' DISTINCT
opé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 BY
clause:
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!
[
et]
ID
colonnes, donc ID
dans la Invoices
table devient InvoiceID
.
DISTINCT
c'é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é.
DISTINCT
renvoie des lignes distinctes sur toutes les colonnes de la ligne, et non sur des colonnes uniques.