Estou trabalhando com um sistema de compra / fatura de alimentos no MS Access 2013 e estou tentando criar uma consulta SQL que retornará o preço de compra mais recente para cada item de comida individual.
Aqui está um diagrama das tabelas com as quais estou trabalhando:
Meu entendimento do SQL é muito básico e tentei a seguinte consulta (incorreta), na esperança de que ele retornasse apenas um registro por item (por causa do DISTINCT
operador) e que retornasse apenas a compra mais recente (desde que eu fiz isso) 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;
No entanto, a consulta acima simplesmente retorna todas as compras de alimentos (ou seja, vários registros para cada registro [Food items]
), com os resultados classificados por data. Alguém pode me explicar o que estou entendendo mal sobre o DISTINCT
operador? Ou seja, por que não está retornando apenas um registro para cada item [Food items]
?
E, mais importante: qual é a maneira mais simples de extrair os dados mais recentes de compra de alimentos para cada item alimentar, dada a estrutura da tabela mostrada acima ? Eu realmente não me importo tanto com eficiência quanto com simplicidade (o banco de dados com o qual estou trabalhando é bastante pequeno - levará anos até que esteja na faixa de dezenas de milhares de registros). Preocupo-me mais com o fato de a consulta ser compreensível para alguém com pouco conhecimento de SQL.
UPDATE: Tentei, ambas as respostas sugeridas abaixo, e nenhuma delas funciona (elas apenas lançam erros de sintaxe).
Com base nas sugestões abaixo, e lendo mais on-line, escrevi a nova consulta a seguir, usando a função agregada max()
e uma 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];
Mas ainda estou tendo o mesmo problema: ou seja, continuo vendo mais de um resultado para cada item alimentar. Alguém pode explicar por que essa consulta não está retornando apenas a compra mais recente para cada item de alimento?
ATUALIZAÇÃO 2 (RESOLVIDO!) :
Nenhuma das respostas abaixo deu muito certo, mas com base em algumas modificações pesadas da resposta de Vladimir abaixo , consegui criar as seguintes consultas, que parecem estar fornecendo os resultados corretos.
Primeiro, criei essa exibição e o nomeiei como "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
Em seguida, escrevi outra consulta para obter os campos necessários:
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;
Obrigado a todos vocês que dedicaram um tempo para me ajudar com isso!
[
e]
ID
colunas, para que ID
a Invoices
tabela se torne InvoiceID
.
DISTINCT
era por colunas únicas. Existe um operador análogo que selecionará apenas com base na exclusividade em uma única coluna? Além disso, obrigado pelas dicas sobre convenções de nomenclatura - sim, é muito chato ter que usar em [ ... ]
qualquer lugar ... E posso ver como a inclusão do nome da tabela na coluna ID aumentaria a legibilidade.
DISTINCT
retorna linhas que são distintas em todas as colunas da linha, não em colunas únicas.