1 votos

Seguimiento del punto de división en función del tiempo

Con PostgreSQL 13.6 tener una tabla de múltiples puntos GPS ya agrupados por track_id (número HEX no secuencial), y de donde ST_Makeline se hace para construir una línea.

Algunas de estas pistas tienen un intervalo de tiempo entre ellas superior a un valor determinado (digamos 10 minutos). Es necesario dividir las track_id por donde salen estos huecos, a un track_id (antes de la 1ª brecha) y track_id+1 (después del 1er hueco) ... track_id+n (después de n_st gap).

En track_id es un número HEX no secuencial de intervalos grandes, por lo que no hay problema en añadirle algunas unidades adicionales (1 ó 2 huecos por pista).

La ubicación real geom es irrelevante en el análisis, ya que los puntos de la brecha pueden estar cerca (tiempo pasado en la misma posición) o lejos (sueltos de recepción).

Esto es sólo para limpiar y organizar los datos, antes de cualquier análisis posterior.

Ejemplo de tabla:

track_id

geom

tiempo

123

aaaa

10:01

123

aaab

10:02

123

aaac

10:05

123

aaad

10:45

123

aaae

10:47

123

aaaf

10:49

234

aaab

10:52

234

aaac

10:55

234

aaaa

10:58

para construir, nueva columna 'new_track_id`:

track_id

geom

tiempo

nuevo_track_id

123

aaaa

10:01

123

123

aaab

10:02

123

123

aaac

10:05

123

123

aaad

10:45

124

123

aaae

10:47

124

123

aaaf

10:49

124

234

aaab

10:52

234

234

aaac

10:55

234

234

aaaa

10:58

234

create table public.testtime
        (id SERIAL primary key,
        track_id varchar,
        time1 time);

--Test data:

    insert into public.testtime (track_id, time1)
        values (123,    '10:01:00'),
               (123,    '10:02:00'),
               (123,    '10:05:00'),
               (123,    '10:45:00'),
               (123,    '10:47:00'),
               (123,    '10:49:00'),
               (234,    '10:52:00'),
               (234,    '10:55:00'),
               (234,    '10:58:00');

EDITAR:

para verificar que time_dif es mayor que el umbral:

UPDATE table SET
chk_dif=(CASE WHEN time_dif>'00:10' THEN TRUE END) 

para rellenar la fila después del verdadero : no funciona

UPDATE table SET
chk_dif2=(CASE WHEN chk_dif=TRUE THEN TRUE
               WHEN chk_dif IS NULL THEN (SELECT LAG(chk_dif2 OVER (PARTITION BY track_id ORDER BY time))
               ELSE FALSE END)

Copia el TRUE de chk_dif a chk_dif2, pero no repite el chk_dif2 en las siguientes filas, ha lugar.

Para cambiar el track_id (simplificar por ahora, cambiar el último dígito a 'x' : no es más un HEX, y sólo permite una brecha) buscando mejor

UPDATE table SET
new_track_id =
CASE WHEN chk_dif2=TRUE THEN CONCAT(LEFT(track_id,LENGTH(track_id)),'X') END)

EDIT2:

El problema es en el segundo paso, para copiar el TRUE de las siguientes filas, según corresponda a la segunda parte del segmento.

1voto

anumi Puntos 103

Esto parece una pregunta puramente SQL, por lo que podría ser un mejor ajuste para dba.stackexchange.com, pero, de nuevo, parecía un poco de diversión para un sábado por la mañana. :-)

Esto es horrible, pero parece que funciona:

SELECT
    *,
    SUM(increment) OVER (PARTITION BY track_id ORDER BY time1 ROWS UNBOUNDED PRECEDING) AS idoffset
FROM (SELECT
        *,  
        CASE
          WHEN time1 - LAG(time1) OVER (PARTITION BY track_id ORDER BY time1) > '00:10' THEN 1
          ELSE 0
        END AS increment
      FROM testtime) tt1
;

Salida

 id | track_id |  time1   | increment | idoffset
----+----------+----------+-----------+----------
  1 | 123      | 10:01:00 |         0 |        0
  2 | 123      | 10:02:00 |         0 |        0
  3 | 123      | 10:05:00 |         0 |        0
  4 | 123      | 10:45:00 |         1 |        1
  5 | 123      | 10:47:00 |         0 |        1
  6 | 123      | 10:49:00 |         0 |        1
  7 | 234      | 10:52:00 |         0 |        0
  8 | 234      | 10:55:00 |         0 |        0
  9 | 234      | 10:58:00 |         0 |        0
(9 rows)

Primero utilizamos una función de ventana, como se sugiere en un comentario, para calcular una columna increment que es 1 para la primera muestra de cada nuevo grupo, y 0 en todas las demás. Luego, para cada fila, sumamos los incrementos de todas las filas precedentes del grupo, lo que da el idoffset para añadir al id. No podemos utilizar una función de ventana en una llamada de función de ventana, así que vamos a ir por un sub-select.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X