Sto lavorando con un sistema di acquisto / fatturazione di alimenti in MS Access 2013 e sto cercando di creare una query SQL che restituirà il prezzo di acquisto più recente per ogni singolo prodotto alimentare.
Ecco un diagramma delle tabelle con cui sto lavorando:
La mia comprensione di SQL è molto semplice e ho provato la seguente query (errata), nella speranza che restituisse solo un record per articolo (a causa DISTINCT
dell'operatore) e che restituisse solo l'acquisto più recente (da quando l'ho fatto 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;
Tuttavia, la query sopra restituisce semplicemente tutti gli acquisti di cibo (ovvero più record per ogni record in [Food items]
), con i risultati ordinati in base alla data. Qualcuno può spiegarmi cosa sto fraintendendo DISTINCT
sull'operatore? Cioè, perché non restituisce solo un record per ogni elemento in [Food items]
?
E ancora al punto: qual è il modo più semplice per me di estrarre i dati di acquisto degli alimenti più recenti per ogni singolo prodotto alimentare, data la struttura della tabella mostrata sopra ? Non mi interessa davvero tanto l'efficienza quanto la semplicità (il database con cui sto lavorando è piuttosto piccolo - ci vorranno anni prima che sia compreso tra decine di migliaia di record). Mi interessa di più che la query sia comprensibile per qualcuno con poca conoscenza di SQL.
AGGIORNAMENTO: Così ho provato, entrambe le risposte suggerite di seguito, e nessuna delle due funziona (generano solo errori di sintassi).
Sulla base dei suggerimenti seguenti e delle successive letture online, ho scritto la seguente nuova query, utilizzando la funzione aggregata max()
e una GROUP BY
clausola:
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];
Ma ho ancora lo stesso problema: cioè vedo ancora più di un risultato per ogni alimento. Qualcuno può spiegare perché questa query non sta solo restituendo l'acquisto più recente per ogni prodotto alimentare?
AGGIORNAMENTO 2 (RISOLTO!) :
Nessuna delle risposte di seguito ha funzionato abbastanza, ma sulla base di una pesante modifica della risposta di Vladimir di seguito , sono stato in grado di creare le seguenti query, che sembrano dare i risultati corretti.
Innanzitutto, ho creato questa vista e l'ho chiamata "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
Quindi ho scritto un'altra query per inserire i campi di cui avevo bisogno:
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;
Grazie a tutti voi che avete dedicato del tempo per aiutarmi in questo!
[
e]
ID
colonne, così diventa ID
nella Invoices
tabella InvoiceID
.
DISTINCT
fosse per colonne singole. Esiste un operatore analogo che selezionerà solo in base all'unicità in una singola colonna? Inoltre, grazie per i suggerimenti sulle convenzioni di denominazione - sì, è molto fastidioso doverlo usare [ ... ]
ovunque ... E posso vedere come l'inclusione del nome della tabella nella colonna ID aumenterebbe la leggibilità.
DISTINCT
restituisce righe distinte tra tutte le colonne della riga, non singole colonne.