Мисля, че това отговаря на очаквания ви резултат:
select "user", "contact", "barcode", "date", "in", "out","dif"
, sum("in"-"out") over(partition by "user", "contact") as "sum"
from (
select "user", "contact", "barcode", "date", "in", "out","dif"
, lag(dif,1) over(partition by "user", "contact" order by "date" ASC) prevdif
, row_number() over(partition by "user", "contact" order by "date" DESC) rn
from "table1"
where date_trunc('day', "date") <= '2017-06-25' ::date - ( interval '1 week')::interval
and "date" > '2017-06-25'::date - ( interval '2 weeks')::interval
) d
where rn in (1,2) and prevdif is not null
order by 1,2,4 DESC
Резултат:
+----+-------+----------------+---------+---------------------+-----+-----+-----+-----+
| | user | contact | barcode | date | in | out | dif | sum |
+----+-------+----------------+---------+---------------------+-----+-----+-----+-----+
| 1 | USER2 | Guillermo Tole | 987654 | 16.06.2017 05:27:00 | 500 | 420 | 80 | 170 |
| 2 | USER2 | Guillermo Tole | 281460 | 15.06.2017 05:36:00 | 310 | 220 | 90 | 170 |
| 3 | USER3 | Juan Rulfo | 123456 | 15.06.2017 05:37:00 | 450 | 300 | 150 | 150 |
| 4 | USER3 | Pepito Marquez | 346234 | 15.06.2017 05:37:00 | 600 | 360 | 240 | 240 |
+----+-------+----------------+---------+---------------------+-----+-----+-----+-----+
Вижте:http://rextester.com/ISHS42170
За условия като "най-скорошно" намирам, че използването на ROW_NUMBER() OVER() е най-удобното, тъй като позволява да се върне целият ред на всяко "най-скорошно" събитие, което не е толкова просто, ако се използва MAX() и ГРУПИРАЙ ПО. „Отделните“ резултати се връщат чрез филтриране на редовете със стойност 1, върната от функцията.
+РЕДАКТИРАНЕ
Вместо да използвате where rn in (1,2)
Вярвам, че по-добрият начин би бил да се използва баркод в условията OVER(PARTITION BY...), като това:
select "user", "contact", "barcode", "date", "in", "out","dif"
, sum("in"-"out") over(partition by "user", "contact") as "sum"
from (
select "user", "contact", "barcode", "date", "in", "out","dif"
, lag(dif,1) over(partition by "user", "contact", "barcode" order by "date" ASC) prevdif
, row_number() over(partition by "user", "contact", "barcode" order by "date" DESC) rn
from "table1"
where date_trunc('day', "date") <= '2017-06-25' ::date - ( interval '1 week')::interval
and "date" > '2017-06-25'::date - ( interval '2 weeks')::interval
) d
where rn = 1 and prevdif is not null
order by 1,2,4 DESC