-- join the item details with the purchase events and save the results in a CTE
with purchased_items as (
SELECT * FROM events
JOIN items ON events.item_id = items.id
WHERE type = 'purchase'
)
SELECT
a.name as item_a,
b.name as item_b,
count(*)::INT as count
-- the central trick to this query is joining the table on itself,
-- creating a pair for each combination of rows that have the same session id
FROM purchased_items a
JOIN purchased_items b
ON a.ga_session_id = b.ga_session_id
-- we only want one record per pair, if we have a+b we dont want b+a
WHERE a.name < b.name
-- group by lets us count all the pairs
GROUP BY a.name, b.name
-- this limits our results to pairs with more than 5 occurrences
HAVING count > 5
ORDER BY count DESC