Я бы предложил два уровня агрегирования:
SELECT SUM(page_views)
FROM (SELECT s.id, SUM(s.page_views) as page_views
FROM sessions s
WHERE s.session_index < 3
GROUP BY s.id
HAVING CCOUNT(s.order_id) > 0 AND -- users have made a purchase
SUM(CASE WHEN s.session_index = 1 THEN 1 ELSE 0 END) > 0 AND
SUM(CASE WHEN s.session_index = 2 THEN 1 ELSE 0 END) > 0
) s;
Тем не менее, ваша исходная версия с правильными индексами и использованием EXISTS
может быть самым быстрым методом:
SELECT SUM(s.page_views)
FROM sessions s
WHERE a.session_index < 3 AND
EXISTS (SELECT 1
FROM sessions s2
WHERE s2.id = s.id AND s2.order_id NOT NULL
) AND
EXISTS (SELECT 1
FROM sessions s2
WHERE s2.id = s.id AND s2.session_index = 1
) AND
EXISTS (SELECT 1
FROM sessions s2
WHERE s2.id = s.id AND s2.session_index = 2
) ;
И нужный вам индекс находится на sessions(id, session_index, order_id)
.