Question

I have a table which has info about visitors to our website.

So it will look like

VISITOR_ID EVENT Date Rank ( I already ranked them portioned by event)

Visitor_id  Event       Date    rank
1           visit       1/1/14  1
1           purchase    1/2/14  2
1           visit       1/3/14  3
1           visit       1/4/14  4
1           purchase    1/5/14  5
1           visit       1/6/14  6
1           visit       1/7/14  7
1           visit       1/8/14  8
1           purchase    1/9/14  9

I want to find all the min and max visit dates ( so the first and last visit before every purchase every user made) before every purchase so the result should have dates

visitor   mindate       maxdate 
1         1/1/2014      1/1/2014 (in this scenario there was only one visit before a purchase)
1         1/3/2014      1/4/2014 ( 2 OR MORE VISITS BEFORE A PURCHASE)
1         1/6/2014      1/8/2014 

This is just an example for one visitor. The table has around a million visitors. Please help.

Was it helpful?

Solution

You need to break the visits into groups. You can do this with a simple trick. If you enumerate the rows for visits and subtract from the rank, then each group will have a constant value. So, this is easy:

select visitor, min(date) as mindate, max(date) as maxdate
from (select t.*, row_number() over (partition by visitor order by rank) as v_rank
      from table t
      where event = 'Visit'
     ) t
group by visitor, (rank - v_rank);

OTHER TIPS

Here's another alternative:

SELECT
    visitor_id
    , MIN(Date)
    , MAX(Date)
FROM
visitors v
INNER JOIN
(SELECT 
    rank
FROM visitors
WHERE Event = 'purchase' AND v.visitor_id = visitors.visitor_id) purchases
WHERE v.rank < purchases.rank
GROUP BY v.visitor_id, v.rank;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top