There are two tables: person and invoice there are many invoice rows for each person, and I want select all persons info with last invoice amount of them.
Person
code | Name | ....
1 | name1
2 | name1
3 | name1
Invoice
ID | person_code | amount | date
1 | 2 | 30000 | 12
2 | 1 | 40000 | 10
3 | 3 | 50000 | 12
4 | 2 | 60000 | 14
5 | 3 | 70000 | 12
6 | 2 | 80000 | 12
7 | 1 | 90000 | 18
I want select
person code | person name | last amount
1 | name1 | 90000
2 | name2 | 60000
3 | name3 | 70000
or
SELECT person.code , person.name , lastinvoice.amount
FROM person
LEFT JOIN
(SELECT * FROM invoice where invoice.person_code=person.code order by date, ID) as
lastinvoice ON lastinvoice.person_code = person.code
This query does not work on ms access:
select * from invoice as i where id=(select max(id) from invoice where personCode=i.personcode and date=( select max(date) from invoice where personCode=i.PersonCode
You can do
SELECT p.code, p.name, i.amount
FROM person p
INNER JOIN invoice i on i.person_code = p.code AND i.date =
(SELECT MAX(date) FROM invoice WHERE person_code = p.code)
AND i.ID = (SELECT MAX(ID) FROM invoice where person_code = p.code AND ID = i.ID)
I've tested this, and it works fine!
Since there can be multiple payments for the same person, on the same date, you need a way to break the tie to find the latest payment. While not great.. you could use the ID
column (autonumber). However, that requires an additional query: one to get the max date and another to get the max ID
for that date.
SELECT p.code, i.[Date], i.amount
FROM Person p INNER JOIN
( Invoice i INNER JOIN
(
SELECT MAX(mxi.ID) AS MaxID, mxi.person_code, mxd.latestDate
FROM Invoice mxi INNER JOIN
(
SELECT person_code, MAX([Date]) AS LatestDate
FROM Invoice
GROUP BY person_code
) mxd ON mxd.person_code = mxi.person_code AND mxd.latestDate = mxi.[Date]
GROUP BY mxi.person_code, mxd.latestDate
) lt ON lt.MaxID = i.ID
) ON p.code = i.person_code
Now for the problem. The query above works until you change the first join from INNER
to LEFT
. Then Access complains it is too complex/ambiguous. (Maybe someone more familiar with Access could rewrite it to satisfy its limitations.) Otherwise, you may have to split part of the sql into a view/stored query. Then JOIN to the view/stored query. Like I said.. it often gets convoluted. But it is the only way I can think of to make Access happy.
vLatestInvoice (Stored Query/View)
SELECT i.ID, i.person_code, i.[Date], i.amount
FROM Invoice AS i INNER JOIN
( SELECT MAX(mxi.ID) AS MaxID, mxi.person_code, mxd.latestDate
FROM Invoice mxi INNER JOIN
(
SELECT person_code, MAX([Date]) AS LatestDate
FROM Invoice
GROUP BY person_code
) mxd ON mxd.person_code = mxi.person_code AND mxd.latestDate = mxi.[Date]
GROUP BY mxi.person_code, mxd.latestDate
) AS lt ON lt.MaxID = i.ID;
Main Query:
SELECT p.code, l.[Date], l.amount
FROM Person p LEFT JOIN vLatestInvoice l ON l.person_code = p.code
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.