Postgresql matching purchases with most recent device loggedin
-
21-12-2019 - |
Question
In my application, I store logins with user_id, device_id(ifa) and login date in table called sessios_logs. And I store purchases with user_id, amount and purchase date in table called purchases.
Below are the example outputs of these two tables where I try to match corresponding ifa values from session_logs for each purchase.
session_logs
uid ifa date
7560168721 CCC 1
7560168721 AAA 3
7560168721 BBB 5
7560168721 AAA 8
7560168721 AAA 10
purchases
uid amount date <ifa>?
7560168721 $1 2 CCC
7560168721 $9 4 AAA
7560168721 $5 7 BBB
7560168721 $4 11 AAA
So how can I find the closest login date and ifa value for each purchase?
I don't know how to iterate for each row while checking the maximum date in the session_logs and having login date earlier than purchase date.
Thanks.
Solution
You can use one of the window functions to match the purchase date to the closest session date.
SELECT uid, amount, date, ifa
FROM
(SELECT
t1.uid,
t2.amount,
t2.date AS date,
ROW_NUMBER() OVER (PARTITION BY t1.uid, t2.date) AS rn,
t1.ifa
FROM
session_logs t1
JOIN purchases t2 ON
t1.uid = t2.uid AND
t1.date <= t2.date) x1
WHERE x1.rn = 1
OTHER TIPS
You can use the window functions, however sadly they are not allowed in the WHERE
part so hence there is a wrapper query around it:
select
uid,
amount,
date,
ifa
from
(
select
l.uid,
amount,
p.date as date,
max(l.date) over (partition by l.uid, p.date) as max_date,
l.ifa
from
session_logs l
join purchases p on
l.uid = p.uid and
l.date <= p.date
-- where l_date = max(l.date) over (partition by l.uid, p.date)
) t
where l_date=max_date;
select
uid,
amount,
date,
(
select ifa
from session_logs
where
uid = purchases.uid and
date < purchases.date
order by date desc
limit 1
)
from purchases;