Các truy vấn SQL chỉ hiển thị các bản ghi mua gần đây nhất cho các mặt hàng thực phẩm riêng lẻ


8

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: Các bảng trong cơ sở dữ liệu MS Access

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ì DISTINCTtoá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ề DISTINCTnhà đ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()GROUP BYmệ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!


2
DISTINCTtrả 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.
Max Vernon

2
Chỉ cần một lời khuyên, tránh sử dụng khoảng trắng trong tên bảng và cột của bạn. Sau đó, bạn sẽ không cần phải bao quanh mọi thứ với []
Max Vernon

1
Và tốt nhất là bao gồm tên của bảng trong tất cả các IDcột, vì vậy IDtrong Invoicesbảng sẽ trở thành InvoiceID.
Max Vernon

Ồ, điều đó có ý nghĩa - tôi nghĩ đó DISTINCTlà 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.
J. Taylor

Câu trả lời:


7

MS Access khá hạn chế.

Tôi cho rằng có thể có nhiều hơn một hóa đơn cho cùng một ngày. Trong trường hợp này, tôi sẽ chọn một hóa đơn có ID cao nhất.

Đầu tiên, chúng tôi sẽ tìm thấy Ngày Hóa đơn tối đa cho mỗi Mặt hàng Thực phẩm.

SELECT
    FPD1.[Food item ID] AS ItemID
    ,MAX(I1.[Invoice Date]) AS MaxDate
FROM
    [Food purchase data] AS FPD1
    INNER JOIN Invoices AS I1 ON I1.ID = FPD1.[Invoice ID]
GROUP BY
    FPD1.[Food item ID]

Vì có thể có một số hóa đơn cho ngày tối đa được tìm thấy, chúng tôi sẽ chọn một hóa đơn có ID tối đa cho mỗi Mục

Dựa trên cú pháp MS Access của các phép nối lồng nhau và sử dụng ví dụ này từ các tài liệu:

SELECT fields 
FROM 
  table1 INNER JOIN 
  (
      table2 INNER JOIN 
      (
          table3 INNER JOIN tablex ON table3.field3 = tablex.fieldx
      ) ON table2.field2 = table3.field3
  ) ON table1.field1 = table2.field2
;

Hãy thử kết hợp nó lại:

SELECT
    InvoicesMaxDate.ItemID
    ,InvoicesMaxDate.MaxDate
    ,MAX(I2.ID) AS MaxInvoiceID
FROM
    (
        SELECT
            FPD1.[Food item ID] AS ItemID
            ,MAX(I1.[Invoice Date]) AS MaxDate
        FROM
            [Food purchase data] AS FPD1
            INNER JOIN Invoices AS I1 ON I1.ID = FPD1.[Invoice ID]
        GROUP BY
            FPD1.[Food item ID]
    ) AS InvoicesMaxDate INNER JOIN
    (
        [Food purchase data] AS FPD2 
        INNER JOIN Invoices AS I2 ON I2.ID = FPD2.[Invoice ID]
    ) ON
        InvoicesMaxDate.ItemID = FPD2.[Food item ID] AND
        --- you may need to put extra "ON" here as well, not sure
        InvoicesMaxDate.MaxDate = I2.[Invoice Date]
GROUP BY
    InvoicesMaxDate.ItemID
    ,InvoicesMaxDate.MaxDate

Bây giờ chúng tôi có cả ItemID và ID của Hóa đơn cuối cùng cho Mục đó. Tham gia vào bảng gốc để lấy các chi tiết khác (cột).

SELECT
    FI3.Item
    ,FI3.Item
    ,FPD3.[Price per unit]
    ,FPD3.[Purchase unit]
    ,I3.[Invoice Date]
FROM
    (
        SELECT
            InvoicesMaxDate.ItemID
            ,InvoicesMaxDate.MaxDate
            ,MAX(I2.ID) AS MaxInvoiceID
        FROM
            (
                SELECT
                    FPD1.[Food item ID] AS ItemID
                    ,MAX(I1.[Invoice Date]) AS MaxDate
                FROM
                    [Food purchase data] AS FPD1
                    INNER JOIN Invoices AS I1 ON I1.ID = FPD1.[Invoice ID]
                GROUP BY
                    FPD1.[Food item ID]
            ) AS InvoicesMaxDate INNER JOIN
            (
                [Food purchase data] AS FPD2 
                INNER JOIN Invoices AS I2 ON I2.ID = FPD2.[Invoice ID]
            ) ON
                InvoicesMaxDate.ItemID = FPD2.[Food item ID] AND
                InvoicesMaxDate.MaxDate = I2.[Invoice Date]
        GROUP BY
            InvoicesMaxDate.ItemID
            ,InvoicesMaxDate.MaxDate
    ) AS LastInvoices INNER JOIN
    (
        [Food items] AS FI3 INNER JOIN
        (
            [Food purchase data] AS FPD3
            INNER JOIN Invoices AS I3 ON I3.ID = FPD3.[Invoice ID]
        ) ON FI3.ID = FDP3.[Food item ID]
    ) ON
        LastInvoices.MaxInvoiceID = I3.ID AND
        LastInvoices.ItemID = FI3.ID

Trong thực tế, tôi sẽ tạo một chế độ xem cho truy vấn đầu tiên với một lần tham gia. Sau đó, tôi sẽ tạo chế độ xem thứ hai tham gia chế độ xem đầu tiên với các bảng, sau đó là chế độ xem thứ ba, v.v., để tránh các tham gia lồng nhau hoặc thu nhỏ chúng. Truy vấn tổng thể sẽ dễ đọc hơn.


Chỉnh sửa để làm rõ những gì tôi muốn nói dựa trên giải pháp cuối cùng của bạn mà bạn đặt vào câu hỏi.

Một nỗ lực cuối cùng để truyền tải thông điệp của tôi.

Đây là những gì bạn đã viết dựa trên đề xuất của tôi ở trên:

SELECT
    InvoicesMaxDate.ItemID
    ,InvoicesMaxDate.MaxDate
    ,Invoices.[Invoice ID]
FROM [Food purchase data], Invoices, 
    (
        SELECT 
            [Food purchase data].[Food item ID] AS ItemID
            ,MAX(Invoices.[Invoice Date]) AS MaxDate
        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
    Invoices.[Invoice ID] = [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, Invoices.[Invoice ID];

Ý tôi là đây:

SELECT
    InvoicesMaxDate.ItemID
    ,InvoicesMaxDate.MaxDate
    ,MAX(Invoices.[Invoice ID]) AS [Invoice ID]
FROM [Food purchase data], Invoices, 
    (
        SELECT
            [Food purchase data].[Food item ID] AS ItemID
            ,MAX(Invoices.[Invoice Date]) AS MaxDate
        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
    Invoices.[Invoice ID] = [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;

Bạn có thấy sự khác biệt?

Trả InvoicesMaxDatevề MAX Invoice Datecho mỗi Food item ID. Nếu có hai hóa đơn giống nhau Food item IDvới cùng một MAX, Invoice Datechúng ta nên chọn một hóa đơn trong số chúng. Điều này được thực hiện bằng cách nhóm bởi InvoicesMaxDate.ItemID, InvoicesMaxDate.MaxDate. Không nên nhóm Invoices.[Invoice ID]ở đây, vì chúng tôi muốn chọn hóa đơn có ID tối đa.

Khi bạn đã lưu truy vấn này dưới dạng LatestInvoicesxem, nó sẽ được sử dụng thêm khi bạn viết đúng (lưu ý rằng truy vấn cuối cùng sử dụng LatestInvoices.[Invoice ID]LatestInvoices.ItemID, nhưng không sử dụng LatestInvoices.MaxDate):

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]
    ,Invoices.[Invoice Date]
FROM [Food items], [Food purchase data], Invoices, LatestInvoices
WHERE 
    Invoices.[Invoice ID] = [Food purchase data].[Invoice ID] AND
    [Food items].ID = [Food purchase data].[Food item ID] AND
    LatestInvoices.[Invoice ID] = Invoices.[Invoice ID] AND 
    LatestInvoices.ItemID = [Food items].ID
ORDER BY [Food items].Item

Về phần, tại sao truy vấn cuối cùng của bạn trong câu hỏi trả về một số hàng cho mỗi Mục:

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];

Bạn đang nhóm ở đây [Food item ID][Price per unit], vì vậy bạn sẽ nhận được nhiều hàng như có sự kết hợp độc đáo của hai cột này.

Các truy vấn sau đây sẽ trả về một hàng mỗi [Food item ID].

SELECT 
    [Food purchase data].[Food item ID]
    , max(Invoices.[Invoice Date]) AS MostRecentInvoiceDate
FROM [Food purchase data], Invoices
GROUP BY [Food purchase data].[Food item ID];

Một lưu ý phụ, bạn thực sự nên sử dụng rõ ràng INNER JOINthay vì ,. Cú pháp đó là 20 tuổi.

SELECT 
    [Food purchase data].[Food item ID]
    , max(Invoices.[Invoice Date]) AS MostRecentInvoiceDate
FROM
    [Food purchase data]
    INNER JOIN Invoices ON Invoices.ID = [Food purchase data].[Invoice ID]
GROUP BY [Food purchase data].[Food item ID];

Cảm ơn câu trả lời rất chi tiết của bạn! Truy vấn đầu tiên bạn chia sẻ đã hoạt động và thực sự đã lấy ngày hóa đơn gần đây nhất cho từng mặt hàng thực phẩm riêng lẻ, điều này thực sự hữu ích. Tuy nhiên, khi tôi thử 2 truy vấn tiếp theo mà bạn chia sẻ, tôi có "Syntax error (missing operator) in query expression"biểu hiện INNER JOIN Invoices AS I2 ON I2.ID = FPD2.[Invoice ID]... Tôi sẽ chơi xung quanh với nó nhiều hơn để xem liệu tôi có thể làm cho nó hoạt động không.
J. Taylor

@JesseTaylor, rõ ràng, cần phải đặt dấu ngoặc rõ ràng ()khi truy vấn sử dụng một số phép nối và để di chuyển ONmệnh đề xung quanh một chút. Tôi không có quyền truy cập để kiểm tra, nhưng tôi có thể cố gắng đoán đúng cú pháp bằng cách đọc các tài liệu sau ngày hôm nay.
Vladimir Baranov

@JesseTaylor, tôi đã cập nhật câu trả lời và hy vọng tôi đoán đúng cú pháp. Hãy thử nó và cho tôi biết nếu nó hoạt động.
Vladimir Baranov

1
@JlieTaylor, bạn được chào đón. Đã được một thời gian kể từ khi tôi sử dụng Access và thật khó để hiểu đúng cú pháp của nó. Một lưu ý về quan điểm của bạn LatestInvoices: trận chung kết GROUPchỉ nên BY InvoicesMaxDate.ItemID, InvoicesMaxDate.MaxDate, không có Invoices.[Invoice ID]. Trong SELECTphần nên có MAX(Invoices.[Invoice ID]) AS [Invoice ID]. Đây là điểm hoàn chỉnh. Đầu tiên (trong truy vấn bên trong) chúng tôi GROUP BY [Food item ID]và tìm Ngày hóa đơn tối đa. Có thể có một số hóa đơn có ngày này, vì vậy có một giây GROUP BYđể chọn hóa đơn có ID tối đa trong số đó.
Vladimir Baranov

1
@JlieTaylor, Thật không may, bạn đã hiểu lầm tôi. Tôi cập nhật câu trả lời của tôi để cho bạn thấy những gì tôi có ý nghĩa. Để xem sự khác biệt, hãy thêm hai hóa đơn vào dữ liệu (mẫu) của bạn cho cùng ItemIDmột ngày lớn và thử cả hai truy vấn.
Vladimir Baranov

3

Một truy vấn chỉ hoạt động ngoài hộp:

SELECT Fi.Item, Fpd.[Price per unit], Fpd.[Purchase unit]
FROM [Food items] Fi INNER JOIN [Food purchase data] Fpd
ON Fpd.[Food item ID] = Fi.ID
WHERE Fpd.[Invoice ID] = (
  SELECT TOP 1 I.ID 
  FROM Invoices I INNER JOIN [Food purchase data] Fpd2
  ON Fpd2.[Invoice ID] = I.ID
  WHERE Fpd2.[Food item ID] = Fpd.[Food item ID]
  ORDER BY I.[Invoice Date] DESC
)

Khi tôi chạy truy vấn này, tôi chỉ gặp một lỗi: "Nhiều nhất một bản ghi có thể được trả về bởi truy vấn con này." Chế độ xem biểu dữ liệu chỉ hiển thị một bản ghi với "#NAME?" trong mọi lĩnh vực.
J. Taylor

3

Tôi có thể giải quyết nó bằng truy vấn sau:

Select MAX(AllItemBuyings.[invoice date]) as RecentBuyingDate, AllItemBuyings.[Food Item Id]  From 
(    
    select fpd.[Invoice Id], fpd.[Food Item Id], I.[invoice date] From [Food purchase data]as fpd 
    inner join invoices I on fpd.[Invoice Id] = I.ID

) as AllItemBuyings    
Group By AllItemBuyings.[Food Item Id]

Vì tôi không có Access nên tôi đã kiểm tra cái này trên SQL Server. Tôi hy vọng điều này sẽ làm việc cho bạn.

Chỉnh sửa / Truy vấn bổ sung : Để thêm các cột khác của bảng mục thực phẩm, tôi đã thay đổi truy vấn. Tôi đã làm nó theo cách mà tôi không thực sự thích. Nếu nó ổn cho bạn phụ thuộc vào dữ liệu và yêu cầu của bạn. Tôi đã tham gia lại bảng HÓA ĐƠN bằng cách sử dụng Ngày đặt hàng. Trong trường hợp đây là một ngày bao gồm cả thời gian mà tôi làm việc, xin vui lòng lưu ý về điều đó. Tôi không thấy một cách khác trong kịch bản của bạn. Có lẽ có một giải pháp tốt hơn bằng cách sử dụng truy vấn đệ quy ...?

Vui lòng thử lại và cho tôi biết nếu nó hoạt động:

Select Recents.RecentBuyingDate, pd.* From 
(

   Select MAX(AllItemBuyings.[invoice date]) as RecentBuyingDate, AllItemBuyings.[Food Item Id]    From 
    (    
        select fpd.[Invoice Id], fpd.[Food Item Id], I.[invoice date], fpd.ID From [Food purchase data]as fpd 
        inner join invoices I on fpd.[Invoice Id] = I.ID

    ) as AllItemBuyings    
    Group By AllItemBuyings.[Food Item Id]

    ) as Recents    
    Join Invoices i on i.[invoice date] = Recents.RecentBuyingDate
    Join [Food purchase data] pd ON pd.[Invoice Id] = i.ID AND pd.[Food Item Id] = Recents.[Food Item Id]

Cảm ơn bạn. Điều này chính xác cho tôi ngày mua gần đây nhất cho mỗi mặt hàng. Làm thế nào tôi sẽ sử dụng này, tuy nhiên, để kéo trong tất cả các lĩnh vực mà tôi đã đề cập trong câu hỏi (ví dụ Item, Price per unit, vv)?
J. Taylor

Truy vấn mới mà bạn đề xuất chỉ đưa ra một thông báo lỗi không nói gì ngoài "Lỗi cú pháp trong mệnh đề TỪ".
J. Taylor

Có thể Access yêu cầu thao tác THAM GIA chính xác là "THAM GIA THAM GIA". Hãy thử tham gia INNSER THAM GIA thay vì chỉ THAM GIA.
Magier

2

Tôi tin rằng dưới đây nên làm việc.

SELECT fi.[Item], fd.[Price per unit], MAX(i.[Invoice Date])
FROM [Invoices] AS i
INNER JOIN [Food Purchase Data] AS fd
    ON i.ID = fd.[Invoice ID]
INNER JOIN [Food items] AS fi
    ON fd.[Food item ID] = fi.ID
GROUP BY fi.Item, fd.[Price per unit]
ORDER BY i.[Invoice Date] DESC

Về lý do tại sao truy vấn của bạn không trả về kết quả như bạn muốn:

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];

Vấn đề lớn nhất tôi thấy là bạn không thực sự làm gì để tham gia các bảng của mình. Việc "tham gia" ngầm hiện diện bằng cách liệt kê cả hai trong mệnh đề TỪ của bạn sẽ mang lại cho bạn một sản phẩm của Cartesian. Về cơ bản, nó sẽ trả về mọi kết hợp có thể có trong cơ sở dữ liệu của bạn cho các trường bạn đang truy vấn.

Ví dụ: nếu hai bảng có 3 bản ghi thay vì trả về ngày gần nhất, truy vấn của bạn sẽ trả về một cái gì đó như: 1,1 1,2 1,3 2,1 2,2 2,3 3,1 3,2 3 , 3

Điều rất quan trọng là bạn tuyên bố rõ ràng tham gia của bạn. Hai cách bạn có thể làm như vậy trong truy vấn của mình sẽ là:

FROM [Food purchase data] AS fd, [Invoices] AS i
WHERE fd.[Invoice ID] = i.[ID]

HOẶC LÀ

FROM [Food purchase data] AS fd
INNER JOIN [Invoices] AS i
    ON fd.[Invoice ID] = i.[ID]

Các truy vấn được cập nhật, nếu chúng vẫn không hoạt động, hãy thử xóa các bí danh và sử dụng các tên cột đủ điều kiện.



0

Tôi đồng ý với đề xuất của Max về mô hình dữ liệu của bạn. Việc triển khai chúng sẽ giúp SQL của bạn dễ đọc hơn trong thời gian dài.

Như đã nói, DISTINCT sẽ hiển thị các hàng độc đáo. Vì vậy, để chỉ hiển thị gần đây nhất, bạn phải giới hạn các cột được hiển thị.

Hãy thử một cái gì đó như:

SELECT [Food purchase data].[Food item ID], max(Invoices.[Invoice Date]) AS MostRecentInvoiceDate
FROM Invoices 
INNER JOIN ([Food items] ON [Food items].ID = [Food purchase data].[Food item ID]) 
GROUP BY [Food purchase data].[Food item ID]

(Dịch: Đối với mỗi mặt hàng trong cửa hàng, hãy hiển thị ngày hóa đơn gần đây nhất.)

Bạn có thể lưu cái này dưới dạng khung nhìn và sử dụng nó trong một truy vấn khác giống như bạn làm một bảng. Vì vậy, bạn có thể thực hiện tham gia nội bộ trên hóa đơn cho giá mua và tham gia vào các bảng khác nếu bạn cần những chi tiết đó.

(Về mặt lý thuyết, bạn cũng có thể thực hiện một truy vấn lồng nhau, nhưng vì bạn đã yêu cầu đơn giản, nên một truy vấn đã lưu đơn giản hơn.)

CẬP NHẬT dựa trên cập nhật của bạn:

Tôi sẽ sử dụng mệnh đề WHERE thay vì THAM GIA vì tôi không có MS Access tiện dụng. Bạn sẽ có thể sử dụng GUI để tạo các kết nối giữa các bảng trong MS Access dựa trên thông tin này. (Vui lòng cung cấp SQLFiddle nếu bạn thực sự cần trợ giúp khắc phục sự cố.)

Bước 1: Lưu cái này dưới dạng XEM (Ví dụ: "MostRecentInvoice")

SELECT [Food purchase data].[Food item ID] AS FoodItemID, max(Invoices.[Invoice Date]) AS MostRecentInvoiceDate
FROM [Food purchase data], Invoices
WHERE [Food purchase data].[Food item ID] = Invoices.ID
GROUP BY [Food purchase data].[Food item ID];

Bước 2: Sử dụng chế độ xem trong truy vấn thứ 2

SELECT (list all the fields you need here)
FROM MostRecentInvoice, Invoices, etc...
WHERE MostRecentInvoice.FoodItemID = [Food purchase data].[Food item ID] 
AND MostRecentInvoice.MostRecentInvoiceDate = Invoices.[Invoice Date]
AND (whatever else joins you'll need for the other tables)

... Và để trả lời câu hỏi của bạn: Truy vấn thứ 2 trong bản cập nhật không hoạt động vì cột [Giá trên mỗi đơn vị] nằm trong câu lệnh CHỌN và NHÓM THEO của bạn. Điều này về cơ bản có nghĩa là bạn đang yêu cầu xem TẤT CẢ các giá trị có thể có của [Giá trên mỗi đơn vị] mặc dù điều bạn thực sự muốn chỉ là một: giá trị gần đây nhất.


Cảm ơn, nhưng khi tôi cố chạy truy vấn mà bạn đã chia sẻ, tôi chỉ gặp một lỗi: "Lỗi cú pháp trong hoạt động THAM GIA."
J. Taylor

Xin lỗi, tôi không có thời gian để tự tạo các bảng trong Access. Tôi giả sử bạn đã có một chút kinh nghiệm với việc tham gia vì có một số câu hỏi của bạn. Bạn đã thử tạo nó bằng cách thực hiện Tạo -> Truy vấn trong Access?
chabzjo

Truy vấn đầu tiên bạn chia sẻ không cho kết quả chính xác vì dòng WHERE [Food purchase data].[Food item ID] = Invoices.ID... Tôi giả sử bạn có ý WHERE [Food purchase data].[Invoice ID] = Invoices.[Invoice ID]đó nhưng điều đó vẫn trả về nhiều ngày cho mỗi mặt hàng thực phẩm thay vì chỉ gần đây nhất.
J. Taylor
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.