El SQL necesario para esto es brutal; le dará a tu optimizador un entrenamiento bastante serio.
A juzgar por los comentarios después de la pregunta y de la pregunta, el deseo es tratar las secuencias de eventos para un ID de usuario dado en la tabla grande como "contiguas" si todas se encuentran dentro de un intervalo fijo entre eventos adyacentes. A modo de ejemplo, el intervalo fijo será de 3 horas. Estoy codificando para IBM Informix Dynamic Server (por el bien del argumento, la versión 11.70, pero la 11.50 también funcionaría bien). Esto significa que hay una notación idiosincrásica que necesito explicar. Específicamente, la notación 3 UNITS HOUR
denota un intervalo de 3 horas; también podría escribirse INTERVAL(3) HOUR TO HOUR
en el dialecto Informix de SQL, o como INTERVAL '3' HOUR
en SQL estándar.
Hay un par de técnicas cruciales para generar SQL, especialmente SQL complejo. Una es construir el SQL en pasos, poco a poco, ensamblando el resultado final. La otra es asegurarse de tener una especificación clara de lo que está buscando.
En la notación que sigue, la calificación 'para el mismo User_ID' debe tomarse siempre como parte de la expresión.
En la mesa grande, hay tres categorías de rango que queremos considerar antes de unirnos a la mesa pequeña.
- Entradas en las que no hay una fila con una hora de evento antes del evento que está lo suficientemente cerca ni una fila con una hora de evento después del evento que está lo suficientemente cerca. Este es un intervalo de tiempo con la misma hora de inicio y finalización.
- Un par de entradas en la tabla que están lo suficientemente cerca pero para las cuales no hay un evento anterior al evento temprano del par que está lo suficientemente cerca ni un evento posterior al evento tardío del par que está lo suficientemente cerca ni un evento entre la pareja.
- Una secuencia de tres o más entradas en la tabla para la cual existe:
- Ningún evento E1 anterior al primero que esté lo suficientemente cerca
- Ningún evento E2 posterior al último que esté lo suficientemente cerca
- Un evento E3 posterior al primero que está lo suficientemente cerca del primero
- Un evento E4 anterior al último que esté lo suficientemente cerca del último (E4 posiblemente sea el mismo evento que E3)
- No hay un par de eventos E5, E6 entre el más antiguo y el más reciente donde no hay ningún evento entre E5 y E6 pero la brecha entre E5 y E6 es demasiado grande para contar.
Como puede ver en la descripción, ¡este será un SQL aterrador!
NB:El código ya ha sido probado; algunos cambios (principalmente pequeños) fueron necesarios. Un pequeño cambio innecesario fue la adición de cláusulas ORDER BY en consultas intermedias. Otro cambio innecesario fue seleccionar los otros datos de la tabla pequeña para fines de verificación. Esta revisión se realizó sin estudiar la versión modificada publicada por msh210 .
También tenga en cuenta que estoy lejos de estar seguro de que esta es una formulación mínima; puede ser factible clasificar todos los rangos con una sola declaración SELECT en lugar de una UNIÓN de tres declaraciones SELECT (y sería bueno si ese fuera el caso).
Rangos de singleton
-- Ranges of exactly 1 event
SELECT lt1.user_id, lt1.event_time AS min_time, lt1.event_time AS max_time
FROM Large_Table AS lt1
WHERE NOT EXISTS -- an earlier event that is close enough
(SELECT *
FROM Large_Table AS lt3
WHERE lt1.user_id = lt3.user_id
AND lt3.event_time > lt1.event_time - 3 UNITS HOUR
AND lt3.event_time < lt1.event_time
)
AND NOT EXISTS -- a later event that is close enough
(SELECT *
FROM Large_Table AS lt4
WHERE lt1.user_id = lt4.user_id
AND lt4.event_time > lt1.event_time
AND lt4.event_time < lt1.event_time + 3 UNITS HOUR
)
ORDER BY User_ID, Min_Time;
Cordilleras Doubleton
-- Ranges of exactly 2 events
SELECT lt1.user_id, lt1.event_time AS min_time, lt2.event_time AS max_time
FROM Large_Table AS lt1
JOIN Large_Table AS lt2
ON lt1.user_id = lt2.user_id
AND lt1.event_time < lt2.event_time
AND lt2.event_time < lt1.event_time + 3 UNITS HOUR
WHERE NOT EXISTS -- an earlier event that is close enough
(SELECT *
FROM Large_Table AS lt3
WHERE lt1.user_id = lt3.user_id
AND lt3.event_time > lt1.event_time - 3 UNITS HOUR
AND lt3.event_time < lt1.event_time
)
AND NOT EXISTS -- a later event that is close enough
(SELECT *
FROM Large_Table AS lt4
WHERE lt1.user_id = lt4.user_id
AND lt4.event_time > lt2.event_time
AND lt4.event_time < lt2.event_time + 3 UNITS HOUR
)
AND NOT EXISTS -- any event in between
(SELECT *
FROM Large_Table AS lt5
WHERE lt1.user_id = lt5.user_id
AND lt5.event_time > lt1.event_time
AND lt5.event_time < lt2.event_time
)
ORDER BY User_ID, Min_Time;
Se agregó un criterio de 3 horas a la cláusula WHERE externa.
Rangos de eventos múltiples
-- Ranges of 3 or more events
SELECT lt1.user_id, lt1.event_time AS min_time, lt2.event_time AS max_time
FROM Large_Table AS lt1
JOIN Large_Table AS lt2
ON lt1.user_id = lt2.user_id
AND lt1.event_time < lt2.event_time
WHERE NOT EXISTS -- an earlier event that is close enough
(SELECT *
FROM Large_Table AS lt3
WHERE lt1.user_id = lt3.user_id
AND lt3.event_time > lt1.event_time - 3 UNITS HOUR
AND lt3.event_time < lt1.event_time
)
AND NOT EXISTS -- a later event that is close enough
(SELECT *
FROM Large_Table AS lt4
WHERE lt1.user_id = lt4.user_id
AND lt4.event_time > lt2.event_time
AND lt4.event_time < lt2.event_time + 3 UNITS HOUR
)
AND NOT EXISTS -- a gap that's too big in the events between first and last
(SELECT *
FROM Large_Table AS lt5 -- E5 before E6
JOIN Large_Table AS lt6
ON lt5.user_id = lt6.user_id
AND lt5.event_time < lt6.event_time
WHERE lt1.user_id = lt5.user_id
AND lt6.event_time < lt2.event_time
AND lt5.event_time > lt1.event_time
AND (lt6.event_time - lt5.event_time) > 3 UNITS HOUR
AND NOT EXISTS -- an event in between these two
(SELECT *
FROM Large_Table AS lt9
WHERE lt5.user_id = lt9.user_id
AND lt9.event_time > lt5.event_time
AND lt9.event_time < lt6.event_time
)
)
AND EXISTS -- an event close enough after the start
(SELECT *
FROM Large_Table AS lt7
WHERE lt1.user_id = lt7.user_id
AND lt1.event_time < lt7.event_time
AND lt7.event_time < lt1.event_time + 3 UNITS HOUR
AND lt7.event_time < lt2.event_time
)
AND EXISTS -- an event close enough before the end
(SELECT *
FROM Large_Table AS lt8
WHERE lt2.user_id = lt8.user_id
AND lt2.event_time > lt8.event_time
AND lt8.event_time > lt2.event_time - 3 UNITS HOUR
AND lt8.event_time > lt1.event_time
)
ORDER BY User_ID, Min_Time;
Se agregó la cláusula NOT EXISTS anidada omitida en la subconsulta 'grandes brechas'.
Todos los rangos en la tabla grande
Claramente, la lista completa de rangos en la última tabla son la unión de las tres consultas anteriores.
Consulta eliminada por no ser lo suficientemente interesante. Es simplemente la UNIÓN de 3 vías de las consultas separadas anteriores.
Consulta final
La consulta final encuentra los rangos, si los hay, en el resultado de la espantosa UNIÓN de 3 partes que está lo suficientemente cerca de la entrada en la tabla pequeña. Una sola entrada en la tabla pequeña podría caer, digamos, a las 13:00, y podría haber un rango en la tabla grande que termine a las 11:00 y otro que comience a las 15:00. Los dos rangos de la tabla grande están separados (la brecha entre ellos es de 4 horas), pero la entrada en la tabla pequeña está lo suficientemente cerca de ambos para contar. [Las pruebas cubren este caso. ]
SELECT S.User_id, S.Event_Time, L.Min_Time, L.Max_Time, S.Other_Data
FROM Small_Table AS S
JOIN (
-- Ranges of exactly 1 event
SELECT lt1.user_id, lt1.event_time AS min_time, lt1.event_time AS max_time
FROM Large_Table AS lt1
WHERE NOT EXISTS -- an earlier event that is close enough
(SELECT *
FROM Large_Table AS lt3
WHERE lt1.user_id = lt3.user_id
AND lt3.event_time > lt1.event_time - 3 UNITS HOUR
AND lt3.event_time < lt1.event_time
)
AND NOT EXISTS -- a later event that is close enough
(SELECT *
FROM Large_Table AS lt4
WHERE lt1.user_id = lt4.user_id
AND lt4.event_time > lt1.event_time
AND lt4.event_time < lt1.event_time + 3 UNITS HOUR
)
UNION
-- Ranges of exactly 2 events
SELECT lt1.user_id, lt1.event_time AS min_time, lt2.event_time AS max_time
FROM Large_Table AS lt1
JOIN Large_Table AS lt2
ON lt1.user_id = lt2.user_id
AND lt1.event_time < lt2.event_time
AND lt2.event_time < lt1.event_time + 3 UNITS HOUR
WHERE NOT EXISTS -- an earlier event that is close enough
(SELECT *
FROM Large_Table AS lt3
WHERE lt1.user_id = lt3.user_id
AND lt3.event_time > lt1.event_time - 3 UNITS HOUR
AND lt3.event_time < lt1.event_time
)
AND NOT EXISTS -- a later event that is close enough
(SELECT *
FROM Large_Table AS lt4
WHERE lt1.user_id = lt4.user_id
AND lt4.event_time > lt2.event_time
AND lt4.event_time < lt2.event_time + 3 UNITS HOUR
)
AND NOT EXISTS -- any event in between
(SELECT *
FROM Large_Table AS lt5
WHERE lt1.user_id = lt5.user_id
AND lt5.event_time > lt1.event_time
AND lt5.event_time < lt2.event_time
)
UNION
-- Ranges of 3 or more events
SELECT lt1.user_id, lt1.event_time AS min_time, lt2.event_time AS max_time
FROM Large_Table AS lt1
JOIN Large_Table AS lt2
ON lt1.user_id = lt2.user_id
AND lt1.event_time < lt2.event_time
WHERE NOT EXISTS -- an earlier event that is close enough
(SELECT *
FROM Large_Table AS lt3
WHERE lt1.user_id = lt3.user_id
AND lt3.event_time > lt1.event_time - 3 UNITS HOUR
AND lt3.event_time < lt1.event_time
)
AND NOT EXISTS -- a later event that is close enough
(SELECT *
FROM Large_Table AS lt4
WHERE lt1.user_id = lt4.user_id
AND lt4.event_time > lt2.event_time
AND lt4.event_time < lt2.event_time + 3 UNITS HOUR
)
AND NOT EXISTS -- a gap that's too big in the events between first and last
(SELECT *
FROM Large_Table AS lt5 -- E5 before E6
JOIN Large_Table AS lt6
ON lt5.user_id = lt6.user_id
AND lt5.event_time < lt6.event_time
WHERE lt1.user_id = lt5.user_id
AND lt6.event_time < lt2.event_time
AND lt5.event_time > lt1.event_time
AND (lt6.event_time - lt5.event_time) > 3 UNITS HOUR
AND NOT EXISTS -- an event in between these two
(SELECT *
FROM Large_Table AS lt9
WHERE lt5.user_id = lt9.user_id
AND lt9.event_time > lt5.event_time
AND lt9.event_time < lt6.event_time
)
)
AND EXISTS -- an event close enough after the start
(SELECT *
FROM Large_Table AS lt7
WHERE lt1.user_id = lt7.user_id
AND lt1.event_time < lt7.event_time
AND lt7.event_time < lt1.event_time + 3 UNITS HOUR
AND lt7.event_time < lt2.event_time
)
AND EXISTS -- an event close enough before the end
(SELECT *
FROM Large_Table AS lt8
WHERE lt2.user_id = lt8.user_id
AND lt2.event_time > lt8.event_time
AND lt8.event_time > lt2.event_time - 3 UNITS HOUR
AND lt8.event_time > lt1.event_time
)
) AS L
ON S.User_ID = L.User_ID
WHERE S.Event_Time > L.Min_Time - 3 UNITS HOUR
AND S.Event_Time < L.Max_Time + 3 UNITS HOUR
ORDER BY User_ID, Event_Time, Min_Time;
OK - advertencia justa; el SQL no ha estado realmente cerca de un SQL DBMS.
El código ahora ha sido probado. La probabilidad infinitesimal era en realidad cero; hubo un error de sintaxis y un par de problemas más o menos menores para resolver.
Experimenté por etapas después de idear los datos de prueba. Utilicé los datos 'Alpha' (ver más abajo) mientras validaba y arreglaba las consultas, y agregué los datos Beta solo para asegurarme de que no hubiera cruces entre los diferentes valores de User_ID.
Usé <
explícito y >
operaciones en lugar de BETWEEN ... AND
para excluir los puntos finales; si desea que los eventos con exactamente 3 horas de diferencia cuenten como 'lo suficientemente cercanos', debe revisar cada desigualdad, posiblemente cambiándolas a BETWEEN ... AND
o posiblemente simplemente usando >=
o <=
según corresponda.
Hay una respuesta a una pregunta vagamente similar pero bastante más simple que (a) escribí y (b) proporcionó algunos pensamientos útiles sobre el procesamiento complejo anterior (en particular, los criterios 'ningún evento antes pero lo suficientemente cerca' y 'ningún evento después pero lo suficientemente cerca') Los criterios de "lo suficientemente cerca" definitivamente complican esta pregunta.
Datos de prueba
Mesa Grande
CREATE TABLE Large_Table
(
Event_Time DATETIME YEAR TO MINUTE NOT NULL,
User_ID CHAR(15) NOT NULL,
Other_Data INTEGER NOT NULL,
PRIMARY KEY(User_ID, Event_Time)
);
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-01 09:15', 'Alpha', 1) { R4 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-01 11:15', 'Alpha', 2) { R4 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-01 13:15', 'Alpha', 3) { R4 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-01 15:15', 'Alpha', 4) { R4 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-01 12:17', 'Beta', 1) { R4 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-02 09:15', 'Alpha', 5) { R1 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-02 10:17', 'Beta', 2) { R1 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-03 09:15', 'Alpha', 6) { R2 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-03 11:15', 'Alpha', 7) { R2 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-03 10:17', 'Beta', 3) { R1 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-04 09:15', 'Alpha', 8) { R3 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-04 11:15', 'Alpha', 9) { R3 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-04 13:15', 'Alpha', 10) { R3 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-04 10:17', 'Beta', 4) { R1 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-05 09:15', 'Alpha', 11) { R2 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-05 11:15', 'Alpha', 12) { R2 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-05 10:17', 'Beta', 5) { R1 };
{ Probe here }
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-05 15:15', 'Alpha', 13) { R2 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-05 17:15', 'Alpha', 14) { R2 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-05 16:17', 'Beta', 6) { R1 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-06 09:15', 'Alpha', 15) { R6 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-06 11:15', 'Alpha', 16) { R6 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-06 13:15', 'Alpha', 17) { R6 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-06 15:15', 'Alpha', 18) { R6 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-06 17:15', 'Alpha', 19) { R6 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-06 19:15', 'Alpha', 20) { R6 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-06 16:17', 'Beta', 7) { R1 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-07 09:15', 'Alpha', 21) { R1 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-07 11:17', 'Beta', 8) { R1 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-07 12:15', 'Alpha', 22) { R1 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-07 13:17', 'Beta', 9) { R1 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-08 09:15', 'Alpha', 23) { R5 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-08 11:15', 'Alpha', 24) { R5 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-08 13:15', 'Alpha', 25) { R5 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-08 15:15', 'Alpha', 26) { R5 };
INSERT INTO Large_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-08 17:15', 'Alpha', 27) { R5 };
Mesa Pequeña
Nota:para fines de prueba, la tabla pequeña en realidad contiene más filas que la tabla grande. Las filas de la tabla pequeña con valores Other_Data mayores de 100 no deberían aparecer en los resultados (y no lo hacen). Las pruebas que se muestran aquí analizan las condiciones del borde.
CREATE TABLE Small_Table
(
Event_Time DATETIME YEAR TO MINUTE NOT NULL,
User_ID CHAR(15) NOT NULL,
Other_Data INTEGER NOT NULL,
PRIMARY KEY(User_ID, Event_Time)
);
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-01 06:15', 'Alpha', 131) { XX };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-01 06:20', 'Alpha', 31) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-01 10:20', 'Alpha', 32) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-01 13:20', 'Alpha', 33) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-01 15:20', 'Alpha', 34) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-01 18:15', 'Alpha', 134) { XX };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-02 06:15', 'Alpha', 135) { XX };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-02 06:16', 'Alpha', 35) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-02 10:20', 'Alpha', 35) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-02 12:14', 'Alpha', 35) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-02 12:15', 'Alpha', 135) { XX };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-03 09:20', 'Alpha', 36) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-03 11:20', 'Alpha', 37) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-04 09:20', 'Alpha', 38) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-04 11:20', 'Alpha', 39) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-04 13:20', 'Alpha', 40) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-05 09:20', 'Alpha', 41) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-05 11:20', 'Alpha', 42) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-05 13:20', 'Alpha', 42) { 22 };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-05 15:20', 'Alpha', 43) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-05 17:20', 'Alpha', 44) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-06 09:20', 'Alpha', 45) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-06 11:20', 'Alpha', 46) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-06 13:20', 'Alpha', 47) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-06 15:20', 'Alpha', 48) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-06 17:20', 'Alpha', 49) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-06 19:20', 'Alpha', 50) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-07 09:20', 'Alpha', 51) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-07 10:20', 'Alpha', 51) { 22 };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-07 12:20', 'Alpha', 52) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-08 09:20', 'Alpha', 53) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-08 11:20', 'Alpha', 54) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-08 13:20', 'Alpha', 55) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-08 15:20', 'Alpha', 56) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-08 17:20', 'Alpha', 57) { YY };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-07 13:27', 'Beta', 9) { R1 };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-07 11:27', 'Beta', 8) { R1 };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-06 16:27', 'Beta', 7) { R1 };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-05 16:27', 'Beta', 6) { R1 };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-05 10:27', 'Beta', 5) { R1 };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-04 10:27', 'Beta', 4) { R1 };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-03 10:27', 'Beta', 3) { R1 };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-02 10:27', 'Beta', 2) { R1 };
INSERT INTO Small_Table(Event_Time, User_ID, Other_Data) VALUES('2012-01-01 12:27', 'Beta', 1) { R4 };
Resultados finales de la consulta
Utilizando los datos anteriores, los resultados obtenidos fueron:
Alpha 2012-01-01 06:20 2012-01-01 09:15 2012-01-01 15:15 31
Alpha 2012-01-01 10:20 2012-01-01 09:15 2012-01-01 15:15 32
Alpha 2012-01-01 13:20 2012-01-01 09:15 2012-01-01 15:15 33
Alpha 2012-01-01 15:20 2012-01-01 09:15 2012-01-01 15:15 34
Alpha 2012-01-02 06:16 2012-01-02 09:15 2012-01-02 09:15 35
Alpha 2012-01-02 10:20 2012-01-02 09:15 2012-01-02 09:15 35
Alpha 2012-01-02 12:14 2012-01-02 09:15 2012-01-02 09:15 35
Alpha 2012-01-03 09:20 2012-01-03 09:15 2012-01-03 11:15 36
Alpha 2012-01-03 11:20 2012-01-03 09:15 2012-01-03 11:15 37
Alpha 2012-01-04 09:20 2012-01-04 09:15 2012-01-04 13:15 38
Alpha 2012-01-04 11:20 2012-01-04 09:15 2012-01-04 13:15 39
Alpha 2012-01-04 13:20 2012-01-04 09:15 2012-01-04 13:15 40
Alpha 2012-01-05 09:20 2012-01-05 09:15 2012-01-05 11:15 41
Alpha 2012-01-05 11:20 2012-01-05 09:15 2012-01-05 11:15 42
Alpha 2012-01-05 13:20 2012-01-05 09:15 2012-01-05 11:15 42
Alpha 2012-01-05 13:20 2012-01-05 15:15 2012-01-05 17:15 42
Alpha 2012-01-05 15:20 2012-01-05 15:15 2012-01-05 17:15 43
Alpha 2012-01-05 17:20 2012-01-05 15:15 2012-01-05 17:15 44
Alpha 2012-01-06 09:20 2012-01-06 09:15 2012-01-06 19:15 45
Alpha 2012-01-06 11:20 2012-01-06 09:15 2012-01-06 19:15 46
Alpha 2012-01-06 13:20 2012-01-06 09:15 2012-01-06 19:15 47
Alpha 2012-01-06 15:20 2012-01-06 09:15 2012-01-06 19:15 48
Alpha 2012-01-06 17:20 2012-01-06 09:15 2012-01-06 19:15 49
Alpha 2012-01-06 19:20 2012-01-06 09:15 2012-01-06 19:15 50
Alpha 2012-01-07 09:20 2012-01-07 09:15 2012-01-07 09:15 51
Alpha 2012-01-07 09:20 2012-01-07 12:15 2012-01-07 12:15 51
Alpha 2012-01-07 10:20 2012-01-07 09:15 2012-01-07 09:15 51
Alpha 2012-01-07 10:20 2012-01-07 12:15 2012-01-07 12:15 51
Alpha 2012-01-07 12:20 2012-01-07 12:15 2012-01-07 12:15 52
Alpha 2012-01-08 09:20 2012-01-08 09:15 2012-01-08 17:15 53
Alpha 2012-01-08 11:20 2012-01-08 09:15 2012-01-08 17:15 54
Alpha 2012-01-08 13:20 2012-01-08 09:15 2012-01-08 17:15 55
Alpha 2012-01-08 15:20 2012-01-08 09:15 2012-01-08 17:15 56
Alpha 2012-01-08 17:20 2012-01-08 09:15 2012-01-08 17:15 57
Beta 2012-01-01 12:27 2012-01-01 12:17 2012-01-01 12:17 1
Beta 2012-01-02 10:27 2012-01-02 10:17 2012-01-02 10:17 2
Beta 2012-01-03 10:27 2012-01-03 10:17 2012-01-03 10:17 3
Beta 2012-01-04 10:27 2012-01-04 10:17 2012-01-04 10:17 4
Beta 2012-01-05 10:27 2012-01-05 10:17 2012-01-05 10:17 5
Beta 2012-01-05 16:27 2012-01-05 16:17 2012-01-05 16:17 6
Beta 2012-01-06 16:27 2012-01-06 16:17 2012-01-06 16:17 7
Beta 2012-01-07 11:27 2012-01-07 11:17 2012-01-07 13:17 8
Beta 2012-01-07 13:27 2012-01-07 11:17 2012-01-07 13:17 9
Resultados intermedios
Formato ligeramente diferente en efecto.
Rangos únicos
Alpha|2012-01-02 09:15|2012-01-02 09:15
Alpha|2012-01-07 09:15|2012-01-07 09:15
Alpha|2012-01-07 12:15|2012-01-07 12:15
Beta|2012-01-01 12:17|2012-01-01 12:17
Beta|2012-01-02 10:17|2012-01-02 10:17
Beta|2012-01-03 10:17|2012-01-03 10:17
Beta|2012-01-04 10:17|2012-01-04 10:17
Beta|2012-01-05 10:17|2012-01-05 10:17
Beta|2012-01-05 16:17|2012-01-05 16:17
Beta|2012-01-06 16:17|2012-01-06 16:17
Rangos de Doubleton
Alpha|2012-01-03 09:15|2012-01-03 11:15
Alpha|2012-01-05 09:15|2012-01-05 11:15
Alpha|2012-01-05 15:15|2012-01-05 17:15
Beta|2012-01-07 11:17|2012-01-07 13:17
Múltiples rangos de eventos
Alpha|2012-01-01 09:15|2012-01-01 15:15
Alpha|2012-01-04 09:15|2012-01-04 13:15
Alpha|2012-01-06 09:15|2012-01-06 19:15
Alpha|2012-01-08 09:15|2012-01-08 17:15