多表连接第二个表上的条件

时间:2012-04-05 10:44:10

标签: sql join one-to-many

有两个表:人和发票 每个人都有很多发票行,我想要选择所有人员信息及其最后发票金额。

code  |  Name | ....
1     |  name1
2     |  name1
3     |  name1

发票

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

我想选择

person code | person name  | last amount
1           |  name1       |  90000
2           |  name2       |  60000
3           |  name3       |  70000

 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

此查询对ms访问不起作用:

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

2 个答案:

答案 0 :(得分:0)

你可以做到

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)

我测试了这个,它运行正常!

答案 1 :(得分:0)

由于同一个人可以多次付款,因此在同一天,您需要一种方法来打破平局以查找最新的付款。虽然不是很好..你可以使用ID列(自动编号)。但是,这需要一个额外的查询:一个用于获取最大日期,另一个用于获取该日期的最大ID

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

现在出现问题。上述查询有效,直到您将第一次加入从INNER更改为LEFT为止。然后Access抱怨它太复杂/含糊不清。 (也许更熟悉Access的人可以重写它以满足其局限性。)否则,您可能必须将部分sql拆分为视图/存储查询。然后JOIN到视图/存储查询。就像我说的那样......它经常变得错综复杂。但这是我能想到让Access满意的唯一方法。

vLatestInvoice (存储查询/查看)

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;

主要查询:

SELECT p.code, l.[Date], l.amount
FROM Person p LEFT JOIN vLatestInvoice l ON l.person_code = p.code