Skip to main content
Announcements
Global Transformation Awards! Applications are now open. Submit Entry
cancel
Showing results for 
Search instead for 
Did you mean: 
Anonymous
Not applicable

Agrupar por días consecutivos

Buenos días,

Tengo que solucionar un problema que me imagino que puede ser bastante común; se trata de agrupar datos de días consecutivos para crear un registro nuevo o asignar una etiqueta:

La table base seria así:

Barco     Fecha         Inicio     Fin          Movs

XXX      01-01-17     13:50     23:20      500

XXX      02-01-17      00:00     05:15     400

YYY     11-04-17       18:30     23:55     350  

YYY     12-04-17       00:00     23:55     800

YYY     13-04_17      00:00     08:30     425

XXX      21-07-17     07:22     14:50     305   

Cada fecha consecutiva para el mismo barco representa una escala. Lo ideal sería poder etiquetar o agruparlas por ejemplo:

opción 1:

Barco  Llegada       h_lleg     Salida          h_sal     Movs

XXX     01-01-17     13:50      02-01-17     05:15     900

YYY     11-04-17     18:30      12-04-17     23:55     1.150

...

opción 2, más sencilla pero también válida, etiquetar cada registro:

Barco     Fecha         Inicio     Fin          Movs     Escala  Día

XXX      01-01-17     13:50     23:20      500                  1

XXX      02-01-17      00:00     05:15     400         1          2

YYY     11-04-17       18:30     23:55     350          1          1 

YYY     12-04-17       00:00     23:55     800          1          2

YYY     13-04_17      00:00     08:30     425           1         3

XXX      21-07-17     07:22     14:50     305            2         1

¿Cúal sería la forma más sencilla de obtenerlo en el script?

Gracias anticipadas!

9 Replies
orguezfaccsa
Contributor II
Contributor II

Buenas Juan Carlos,

    ¿la tabla proviene de una BBDD? Porque si es así podrías hacerlo con una sentencia GROUP BY.

Un saludo

Anonymous
Not applicable
Author

Si, proviene de un BBDD, pero no he conseguido marcar o separar o marcar las escalas como necesito. Cada escala puede tener varios registros en el mismo día, (hay 4 turnos), y/o en días consecutivos.

Si me puedes orientar, lo agradezco, Oscar.

Sl2,

Juan Carlos.

orguezfaccsa
Contributor II
Contributor II

Buenas Juan,

    el contar el número de escalas sería haciendo una SQL donde seleccionaras por barco y fecha el número de registros algo así como: SELECT barco, llegada, COUNT(*) FROM tablaorigen GROUP BY barco, llegada

    El tema de contar los días consecutivos tengo que darle una pensada porque parece más complejo.

Saludos

Anonymous
Not applicable
Author

He encontrado una solución, aunque no se si es la óptima, al menos funciona.

Creo una carga temporal de la base y le añado el número de fila:

Escalas_preparatorio:

load      *,

              RowNo() as num_peticion


Resident Estadisticas order by codbuque,Fecha;


Sobre esta tabla aplico:

Escalas:

load

*,

if(rowno()=1 or codbuque <> previous(codbuque),

RowNo(),

if((Fecha_esc-previous(Fecha_esc))<=5, previous(num_peticion), (num_peticion))) as escala

Resident Escalas_preparatorio order by codbuque,Fecha_esc;

De esta forma obtengo una nueva tabla donde en los días que son consecutivos no coinciden en la misma fila el nº de fila y el nº de escala, con lo que ya los puedo marcar muy fácilmente;

marca_escala.JPG

(Nota: el <=5 es un dato que obtengo por la práctica real en este caso)

orguezfaccsa
Contributor II
Contributor II

Buenas Juan,

    ¿el propósito del campo con escalas es el número de veces que un barco para en una fecha o el número de veces que para en fechas consecutivas?. Por lo que parece es el número de veces que para en fechas consecutivas que no sean superiores a 5 días. El único problema es que si un barco para en su destino final y sale antes de 5 días contaría como escala, ¿no?

    Por cierto buena aproximación. No había usado nunca la función previous, le echaré un vistazo.

Atte.,

O.Rodríguez

Anonymous
Not applicable
Author

Así es; el tiempo que pasan los buques en puerto no es casi nunca igual, sea por la carga, el clima, la congestión... Lo que es igual es la ruta, lo que quiero diferenciar son las veces que llega y sale del puerto, al margen de los registros que haya en el fichero para cada barco llegada.

Lo tengo ya marcado, ahora estoy intentando darle un número correlativo, (el mismo si es la misma escala e incrementado para la siguiente, por si alguien puede ayudar

orguezfaccsa
Contributor II
Contributor II

Juan podrías probar esto:

Escalas_preparatorio:

load      *,

              1 as num_peticion

Resident Estadisticas order by codbuque,Fecha;


Escalas:

load

*,

if(rowno()=1 or codbuque <> previous(codbuque), num_peticion,

if((Fecha_esc-previous(Fecha_esc))<=5, previous(num_peticion)+1, (num_peticion))) as escala

Resident Escalas_preparatorio order by codbuque,Fecha_esc;

Anonymous
Not applicable
Author

Al final, la solución que he conseguido ha sido mucho más sencilla y eficiente.

if((Fecha -previous(Fecha))>1,'Escala','Consecutiva') as Tipo,

    if((Fecha -previous(Fecha))>1,AutoNumber(Fecha),Autonumber(Fecha)) as Numero_esc,

En la primera condición etiqueto si es origen de cada escala,( si el siguiente registro está a más de un día es una nueva escala) y en la segunda si son días consecutivos.

En la segunda le asigna el mismo número a cada escala, por barco.

Anonymous
Not applicable
Author

La solución final ha sido, con las funciones "previous", y "rowno", realizar tantas cargas sucesivas como el máximo de días por escala existente y eliminando las tablas usadas, en las que en cada una completaba el nº de escala asignado al primer día.

De esta forma se usa el nº de fila del primer día como identificador de todos los días sucesivos. Pongo un ejemplo del resultado final.Captura.JPG