En primer lugar la respuesta, utilizando SQL estándar, dado que su hipótesis: hay una mesa de eventos con un diseño simple:
EVENTS
-----------------------------
SESION_ID , EVENT_NAME , TMST
Para obtener la sesión que se lleva a cabo el paso # 1 en algún momento:
-- QUERY 1
SELECT SESSION_ID,MIN(TMST) FROM EVENTS WHERE EVENT_NAME='event1' GROUP BY SESSION_ID;
Aquí hago la suposición de que event1 puede ocurrir más de una vez por sesión. El resultado es una lista de sesión única que demostró event1 en algún momento.
Con el fin de conseguir el paso 2 y paso 3, sólo puede hacer lo mismo:
-- QUERY 2
SELECT SESSION_ID,MIN(TMST) FROM EVENTS WHERE EVENT_NAME='event2' GROUP BY SESSION_ID;
-- QUERY 3
SELECT SESSION_ID,MIN(TMST) FROM EVENTS WHERE EVENT_NAME='event3' GROUP BY SESSION_ID;
Ahora, desea seleccionar las sesiones que realizan el paso 1, paso 2 y paso 3 - en ese orden. Más precisamente, necesita contar las sesiones que realizaron el paso 1, luego contar la sesión que realizó el paso 2, luego contar las sesiones que realizaron el paso 3. Básicamente sólo tenemos que combinar los 3 anteriores consultas con izquierda unirse a la lista de las sesiones que entraron en el embudo y qué pasos se realizan:
-- FUNNEL FOR S1/S2/S3
SELECT
SESSION_ID,
Q1.TMST IS NOT NULL AS PERFORMED_STEP1,
Q2.TMST IS NOT NULL AS PERFORMED_STEP2,
Q3.TMST IS NOT NULL AS PERFORMED_STEP3
FROM
-- QUERY 1
(SELECT SESSION_ID,MIN(TMST) FROM EVENTS WHERE EVENT_NAME='event1' GROUP BY SESSION_ID) AS Q1,
LEFT JOIN
-- QUERY 2
(SELECT SESSION_ID,MIN(TMST) FROM EVENTS WHERE EVENT_NAME='event2' GROUP BY SESSION_ID) AS Q2,
LEFT JOIN
-- QUERY 3
(SELECT SESSION_ID,MIN(TMST) FROM EVENTS WHERE EVENT_NAME='event2' GROUP BY SESSION_ID) AS Q3
-- Q2 & Q3
ON Q2.SESSION_ID=Q3.SESSION_ID AND Q2.TMST<Q3.TMST
-- Q1 & Q2
ON Q1.SESSION_ID=Q2.SESSION_ID AND Q1.TMST<Q2.TMST
El resultado es una lista de sesión única que entró en el embudo en el paso 1, y puede haber seguido el paso 2 y paso 3 ... ej:
SESSION_ID_1,TRUE,TRUE,TRUE
SESSION_ID_2,TRUE,TRUE,FALSE
SESSION_ID_3,TRUE,FALSE,FALSE
...
Ahora sólo tenemos que calcular algunas estadísticas, por ejemplo:
SELECT
STEP1_COUNT,
STEP1_COUNT-STEP2_COUNT AS EXIT_AFTER_STEP1,
STEP2_COUNT*100.0/STEP1_COUNT AS PERCENTAGE_TO_STEP2,
STEP2_COUNT-STEP3_COUNT AS EXIT_AFTER_STEP2,
STEP3_COUNT*100.0/STEP2_COUNT AS PERCENTAGE_TO_STEP3,
STEP3_COUNT*100.0/STEP1_COUNT AS COMPLETION_RATE
FROM
(-- QUERY TO COUNT session at each step
SELECT
SUM(CASE WHEN PERFORMED_STEP1 THEN 1 ELSE 0 END) AS STEP1_COUNT,
SUM(CASE WHEN PERFORMED_STEP2 THEN 1 ELSE 0 END) AS STEP2_COUNT,
SUM(CASE WHEN PERFORMED_STEP3 THEN 1 ELSE 0 END) AS STEP3_COUNT
FROM
[... insert the funnel query here ...]
) AS COMPUTE_STEPS
Et voilà!
Ahora para la discusión. En primer lugar, el resultado es bastante directo, dado que adopta el modo de pensar "establecido" (o funcional) y no el enfoque "procedimental". No visualices la base de datos como una colección de tablas fijas con columnas y filas ... así es como se implementa, pero no es la forma en que interactúas con ella. ¡Son todos sets, y puedes organizar los sets de la forma que necesites!
Segundo punto que la consulta se optimizará automáticamente para ejecutarse en paralelo si está utilizando una base de datos MPP, por ejemplo. Ni siquiera necesita programar la consulta de manera diferente, usar map-reduce o lo que sea ... Ejecuté la misma consulta en el conjunto de datos de prueba con más de 100 millones de eventos y obtuve resultados en segundos.
Por último, pero no menos importante, la consulta abre un sinfín de posibilidades.¡Agrupe los resultados por el receptor, las palabras clave, la página de destino, la información del usuario y analice cuál proporciona la mejor tasa de conversión, por ejemplo!
Bueno, puede obtener todos los eventos por ID de sesión en un reductor si cree que esto lo hace más fácil. –