Estoy trabajando con un sistema de compra / facturación de alimentos en MS Access 2013 y estoy tratando de crear una consulta SQL que devolverá el precio de compra más reciente para cada artículo alimenticio individual.
Aquí hay un diagrama de las tablas con las que estoy trabajando:
Mi comprensión de SQL es muy básica, e intenté la siguiente consulta (incorrecta), con la esperanza de que solo devolvería un registro por artículo (debido al DISTINCT
operador) y que solo devolvería la compra más reciente (ya que lo hice 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;
Sin embargo, la consulta anterior simplemente devuelve todas las compras de alimentos (es decir, múltiples registros para cada registro [Food items]
), con los resultados ordenados por fecha. ¿Alguien puede explicarme lo que estoy entendiendo mal sobre el DISTINCT
operador? Es decir, ¿por qué no devuelve solo un registro para cada elemento [Food items]
?
Y más importante: ¿cuál es la forma más sencilla para mí de obtener los datos de compra de alimentos más recientes para cada artículo de alimentos individual, dada la estructura de la tabla que se muestra arriba ? Realmente no me importa tanto la eficiencia como la simplicidad (la base de datos con la que estoy trabajando es bastante pequeña, pasarán años antes de que esté incluso en el rango de decenas de miles de registros). Me importa más que la consulta sea comprensible para alguien con poco conocimiento de SQL.
ACTUALIZACIÓN: así que lo intenté, las dos respuestas sugeridas a continuación, y ninguna de ellas funciona (simplemente arrojan errores de sintaxis).
Basado en las sugerencias a continuación, y leyendo más en línea, escribí la siguiente nueva consulta, usando la función de agregado max()
y una GROUP BY
cláusula:
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];
Pero sigo teniendo el mismo problema: es decir, sigo viendo más de un resultado para cada alimento. ¿Alguien puede explicar por qué esta consulta no solo devuelve la compra más reciente de cada alimento?
ACTUALIZACIÓN 2 (¡RESUELTO!) :
Ninguna de las respuestas a continuación funcionó, pero en base a algunas modificaciones importantes de la respuesta de Vladimir a continuación , pude crear las siguientes consultas, que parecen estar dando los resultados correctos.
Primero, creé esta vista y la llamé "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
Luego escribí otra consulta para obtener los campos que necesitaba:
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;
¡Gracias a todos los que se tomaron el tiempo para ayudarme con esto!
[
y]
ID
columnas, por lo que ID
en la Invoices
tabla se convierte InvoiceID
.
DISTINCT
era por columnas individuales. ¿Existe un operador análogo que seleccione solo en función de la unicidad en una sola columna? Además, gracias por los consejos sobre convenciones de nomenclatura: sí, es muy molesto tener que usarlo en [ ... ]
todas partes ... Y puedo ver cómo incluir el nombre de la tabla en la columna ID aumentaría la legibilidad.
DISTINCT
devuelve filas que son distintas en todas las columnas de la fila, no en columnas individuales.