Tôi đang làm việc với hệ thống hóa đơn / mua thực phẩm trong MS Access 2013 và đang cố gắng tạo một truy vấn SQL sẽ trả lại giá mua gần đây nhất cho từng mặt hàng thực phẩm riêng lẻ.
Đây là sơ đồ của các bảng tôi đang làm việc với:
Sự hiểu biết của tôi về SQL là rất cơ bản và tôi đã thử truy vấn (không chính xác) sau đây, với hy vọng rằng nó sẽ chỉ trả về một bản ghi cho mỗi mục (vì DISTINCT
toán tử) và nó sẽ chỉ trả về lần mua gần đây nhất (vì tôi đã làm 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;
Tuy nhiên, truy vấn ở trên chỉ đơn giản trả về tất cả các giao dịch mua thực phẩm (nghĩa là nhiều bản ghi cho mỗi bản ghi [Food items]
), với kết quả được sắp xếp giảm dần theo ngày. Ai đó có thể giải thích cho tôi những gì tôi đang hiểu sai về DISTINCT
nhà điều hành? Đó là, tại sao nó không trả lại chỉ một bản ghi cho mỗi mục trong [Food items]
?
Và nhiều hơn nữa đến điểm - là những gì đơn giản nhất cách cho tôi để chỉ cần kéo hầu hết các dữ liệu mua hàng thực phẩm gần đây đối với từng mặt hàng thực phẩm cá nhân, do cấu trúc bảng hiển thị ở trên ? Tôi không thực sự quan tâm đến hiệu quả nhiều như sự đơn giản (cơ sở dữ liệu tôi đang làm việc khá nhỏ - sẽ mất nhiều năm trước khi nó còn trong hàng chục ngàn hồ sơ). Tôi quan tâm nhiều hơn về truy vấn có thể hiểu được đối với người có ít kiến thức về SQL.
CẬP NHẬT: Vì vậy, tôi đã thử, cả hai câu trả lời được đề xuất bên dưới và cả hai câu trả lời đều không hoạt động (chúng chỉ đưa ra lỗi cú pháp).
Dựa trên các gợi ý bên dưới và đọc thêm trực tuyến, tôi đã viết truy vấn mới sau đây, sử dụng hàm tổng hợp max()
và GROUP BY
mệnh đề:
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];
Nhưng tôi vẫn gặp phải một vấn đề tương tự: đó là tôi vẫn thấy nhiều hơn một kết quả cho mỗi mặt hàng thực phẩm. Bất cứ ai cũng có thể giải thích tại sao truy vấn này không chỉ trả lại lần mua gần đây nhất cho mỗi mặt hàng thực phẩm?
CẬP NHẬT 2 (GIẢI QUYẾT!) :
Không có câu trả lời nào dưới đây khá hiệu quả nhưng dựa trên một số sửa đổi nặng nề của câu trả lời của Vladimir bên dưới , tôi có thể tạo các truy vấn sau, dường như cho kết quả chính xác.
Đầu tiên, tôi đã tạo chế độ xem này và đặt tên là "RecentInvoices":
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
Sau đó, tôi đã viết một truy vấn khác để lấy các trường tôi cần:
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;
Cảm ơn tất cả các bạn đã dành thời gian để giúp tôi với điều này!
[
và]
ID
cột, vì vậy ID
trong Invoices
bảng sẽ trở thành InvoiceID
.
DISTINCT
là bởi các cột đơn. Có một toán tử tương tự sẽ chỉ chọn dựa trên tính duy nhất trong một cột không? Ngoài ra, cảm ơn về các mẹo về quy ước đặt tên - vâng, rất khó chịu khi phải sử dụng [ ... ]
ở mọi nơi ... Và tôi có thể thấy cách bao gồm tên bảng trong cột ID sẽ tăng khả năng đọc.
DISTINCT
trả về các hàng khác biệt trên tất cả các cột trong hàng, không phải các cột đơn.