2012-04-05 2 views
0

Es gibt zwei Tabellen: Person und Rechnung es gibt viele Rechnungszeilen für jede Person, und ich möchte alle Personen Informationen mit letzten Rechnungsbetrag von ihnen auswählen.Mehrere Tabelle Join mit Zustand auf zweite Tabelle

Person

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

Rechnung

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 

ich wählenden

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

oder

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 

Diese Abfrage nicht auf MS Access funktioniert:

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 

Antwort

0

Sie tun können

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) 

ich das getestet habe, und es funktioniert gut!

+0

Diese Abfrage hat eine geringe Leistung mit zwei Innen wählen – Hamid

+0

Und ich will es auf beiden MS SQL ausführen und ms Zugang, aber diese Qury Dosis funktioniert nicht auf Zugriff – Hamid

+1

@Hamid: Also, verwenden Sie dies als Grundlage und bauen darauf auf. Niemand hat versprochen, Ihnen einen Code zum Kopieren/Einfügen zu geben. – cHao

0

Da es mehrere Zahlungen für dieselbe Person geben kann, müssen Sie am selben Tag eine Möglichkeit haben, die Zahlung zu unterbrechen, um die letzte Zahlung zu finden. Obwohl nicht großartig .. Sie könnten die ID Spalte (Autonummer) verwenden. Dies erfordert jedoch eine zusätzliche Abfrage: eine, um das maximale Datum zu erhalten, und eine andere, um das Maximum ID für dieses Datum zu erhalten.

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 

Jetzt für das Problem. Die obige Abfrage funktioniert, bis Sie die erste Verknüpfung von INNER zu LEFT ändern. Dann beschwert sich Access, dass es zu komplex/mehrdeutig ist. (Vielleicht könnte jemand, der mit Access vertrauter ist, ihn neu schreiben, um seine Einschränkungen zu erfüllen.) Andernfalls müssen Sie möglicherweise einen Teil des SQL in eine View/Stored Query aufteilen. Dann JOIN zur View/gespeicherten Abfrage. Wie ich schon sagte .. es wird oft verworren. Aber es ist der einzige Weg, wie ich Access glücklich machen kann.

vLatestInvoice (Stored Query/Ansicht)

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; 

Haupt Abfrage:

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