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.

Was it helpful?

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;

http://sqlfiddle.com/#!15/36185/9/0

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;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top