MS Access 2013で食品購入/請求システムを使用していて、個々の食品の最新の購入価格を返すSQLクエリを作成しようとしています。
SQLについての私の理解は非常に基本的です。次の(正しくない)クエリを試してみました。(DISTINCT
演算子のため)アイテムごとに1つのレコードのみが返され、最新の購入のみが返されることを期待しています(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;
ただし、上記のクエリは単にすべての食品購入(つまり、の各レコードの複数のレコード)を返し[Food items]
、結果は日付の降順でソートされます。誰かがDISTINCT
オペレーターについて誤解していることを私に説明できますか?つまり、なぜ各アイテムのレコードが1つだけ返されないの[Food items]
ですか?
そしてもっと重要な点- 上記のテーブル構造を前提として、個々の食品の最新の食品購入データを取得する最も簡単な方法は何ですか?単純さほど効率についてはあまり気にしません(私が使用しているデータベースはかなり小さいです-数万のレコードの範囲になるまでには数年かかります)。SQLの知識がほとんどない人にとっても、クエリが理解可能であることを重視しています。
更新: それで私は試してみました、両方の答えは以下に提案されていて、どちらも機能しません(構文エラーをスローするだけです)。
以下の提案に基づいて、さらにオンラインで読んで、集約関数max()
とGROUP BY
句を使用して、次の新しいクエリを作成しました。
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];
しかし、私はまだ同じ問題を抱えています。つまり、各食品に対して複数の結果が表示されています。このクエリが各食品の最新の購入を返すだけではない理由を誰かが説明できますか?
アップデート2(解決済み!):
以下の回答はどれもうまくいきませんでしたが、以下のウラジミールの回答の大幅な変更に基づいて、正しい結果を提供しているように見える次のクエリを作成できました。
まず、このビューを作成し、「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
次に、必要なフィールドを取得するための別のクエリを作成しました。
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;
これを手伝ってくれてありがとうございました!
[
と]
ID
列にテーブルの名前を含めるのが最善であるためID
、Invoices
テーブルではになりInvoiceID
ます。
DISTINCT
が単一のカラムによるものだと思った 単一の列の一意性のみに基づいて選択する類似の演算子はありますか?また、命名規則のヒントに感謝します-はい、[ ... ]
どこでも使用するのは非常に面倒です...そして、ID列にテーブル名を含めると読みやすさが向上することがわかります。
DISTINCT
単一の列ではなく、行内のすべての列で異なる行を返します。