Mam pod ręką tylko oracle'a do sprawdzenia niestety.
SQL> @@c:/sql/2.sql
SQL> create table partie (
2 id_towaru integer,
3 cena_zakupu number(10,2),
4 ilosc integer,
5 data date
6 );
Table created.
SQL>
SQL> insert into partie values (1,1.44,3,to_date('2011-01-12','YYYY-MM-DD'));
1 row created.
SQL> insert into partie values (2,2.55,3,to_date('2011-01-12','YYYY-MM-DD'));
1 row created.
SQL> insert into partie values (3,5.44,4,to_date('2011-01-12','YYYY-MM-DD'));
1 row created.
SQL> insert into partie values (1,1.70,5,to_date('2011-01-13','YYYY-MM-DD'));
1 row created.
SQL> insert into partie values (1,1.63,6,to_date('2011-01-13','YYYY-MM-DD'));
1 row created.
SQL> insert into partie values (2,3.44,7,to_date('2011-01-13','YYYY-MM-DD'));
1 row created.
SQL> insert into partie values (2,5.42,5,to_date('2011-01-14','YYYY-MM-DD'));
1 row created.
SQL> insert into partie values (3,4.67,2,to_date('2011-01-14','YYYY-MM-DD'));
1 row created.
SQL> insert into partie values (3,5.41,7,to_date('2011-01-14','YYYY-MM-DD'));
1 row created.
SQL>
SQL> select id_towaru, cena_zakupu, ilosc,data
2 from (select p.*, row_number() over (partition by p.id_towaru order by p.data desc, p.rowid desc) rn
3 from partie p)
4 where rn = 2;
ID_TOWARU CENA_ZAKUPU ILOSC DATA
---------- ----------- ---------- --------
1 1,7 5 11/01/13
2 3,44 7 11/01/13
3 4,67 2 11/01/14
SQL>
SQL> drop table partie;
Table dropped.
SQL> exit
Oczywiście w t-sql też jest http://msdn.microsoft.com/pl-pl/library/ms186734.aspx.
Można się obyć bez rowid (którego zresztą nie ma dla sql servera), ale wtedy dostaniesz dla ID_TOWARU = 3 inną wartość niż chciałeś.
Zauważ, że w wypadku dwóch wpisów dla danego id z tą samą datą, nie masz jak rozróżnić który było wcześniej.