es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Encontrar la marca de tiempo más cercana en Redshift SQL

Tengo dos tablas, t1 y t2. Para cada id en t1 tengo varios registros en t2. Quiero relacionar el timestamp más cercano de t2 a cada registro de t1. En t1 hay una bandera, si es 1 quiero relacionar el timestamp más cercano de t2 que sea menor y si es 0 quiero relacionar el timestamp más cercano que sea mayor que el de t1.

En resumen, tengo la siguiente tabla:

T1
id, flag, timestamp

T2
id, timestamp

¿Existe una manera eficiente de hacer esto?

Edit, aquí hay un ejemplo:

T1

customer_id timestamp_t1 flag
1 01.01.21 12:00 1
2 01.01.21 13:00 0

T2

customer_id timestamp_t2 atributos adicionales
1 01.01.21 11:00 atributo1
1 01.01.21 10:00 atributo2
1 01.01.21 13:00 atributo3
2 01.01.21 11:00 atributo4
2 01.01.21 12:00 atributo5
2 01.01.21 14:00 atributo6
2 01.01.21 15:00 atributo7

Resultado:

customer_id timestamp_t1 timestamp_t2 flag atributos adicionales
1 01.01.21 12:00 01.01.21 11:00 1 atributo1
2 01.01.21 13:00 01.01.21 14:00 0 atributo6

Espero que esto ayude. Como puedes ver, en el resultado, relacionamos 11:00 de T2 con 12:00 de T1 porque la bandera era 1, elegimos el timestamp más cercano que fuera menor que 12:00. También relacionamos 14:00 con 13:00, porque la bandera era 0 (así que relacionamos el timestamp más cercano con id 2 que es mayor que 13:00).

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Sí, hay una manera eficiente de hacerlo. Un enfoque es utilizar una subconsulta para obtener el timestamp más cercano para cada registro en t1. La subconsulta utilizará una declaración CASE para verificar el valor de la bandera y seleccionar el timestamp más cercano en consecuencia. Luego, podemos unir el resultado de la subconsulta con t1 y t2 en id y timestamp para obtener los atributos adicionales.

    Aquí tienes un ejemplo de código SQL:

    SELECT t1.id, t1.timestamp, t2.timestamp AS timestamp_t2, t1.flag, t2.additional_attributes
    FROM t1
    JOIN (
      SELECT t1.id, t1.timestamp,
        CASE
          WHEN t1.flag = 1 THEN (
            SELECT MAX(t2.timestamp)
            FROM t2
            WHERE t2.id = t1.id AND t2.timestamp < t1.timestamp
          )
          ELSE (
            SELECT MIN(t2.timestamp)
            FROM t2
            WHERE t2.id = t1.id AND t2.timestamp > t1.timestamp
          )
        END AS closest_timestamp
      FROM t1
    ) AS sub ON t1.id = sub.id AND t1.timestamp = sub.timestamp
    JOIN t2 ON t1.id = t2.id AND sub.closest_timestamp = t2.timestamp;
    

    Esto devolverá una tabla con el ID del cliente, timestamp de T1, timestamp más cercano de T2, valor de la bandera y atributos adicionales de T2.

Comments are closed.