SQL - Restar perido

 
Vista:
sin imagen de perfil

Restar perido

Publicado por Msp (8 intervenciones) el 07/06/2017 21:14:46
Buenas tardes, espero me puedan ayudar, tengo una tabla con el campo Periodo de tipo "int", lo que necesito es que me devuelva la diferencia de meses en la columna DIferencia como muestro en la imagen. Espero su apoyo, muchas gracias.
5
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 806
Bronce
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

Restar perido

Publicado por leonardo_josue (1173 intervenciones) el 07/06/2017 21:45:38
Hola MSP;

En realidad tienes muchas formas de obtener la consulta que quieres, sin embargo, dependerá de cómo tengas almacenada tu información... si estamos hablando de MESES entonces ¿por qué razón tienes un campo tipo INT?... puedo suponer con los valores que estás manejando, las cuatro primeras cifras corresponden al AÑO y las últimas dos corresponden al mes, sin embargo eso no lo especificas en tu post...

El problema básicamente se resolvería encontrando el mes "anterior" para hacer la comparación... como te comenté, tienes varias formas de hacerlo, la más "simple" podría ser con subconsultas:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
mysql> SELECT * FROM tabla;
+---------+
| periodo |
+---------+
|  201601 |
|  201602 |
|  201603 |
|  201605 |
|  201608 |
|  201701 |
+---------+
6 rows in set (0.00 sec)
 
mysql> SELECT periodo, ( SELECT MAX(periodo)
    ->                   FROM tabla T2
    ->                   WHERE T2.periodo < T1.periodo) anterior
    -> FROM tabla T1;
+---------+----------+
| periodo | anterior |
+---------+----------+
|  201601 |     NULL |
|  201602 |   201601 |
|  201603 |   201602 |
|  201605 |   201603 |
|  201608 |   201605 |
|  201701 |   201608 |
+---------+----------+
6 rows in set (0.02 sec)

Ahora, con estas dos columnas podrías obtener el la diferencia que quieres, pero qué pasa si cambias de AÑO, como en el último de los casos:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mysql> SELECT T.periodo, T.anterior, T.anterior - T.periodo diferencia
    -> FROM
    -> (
    ->   SELECT periodo, ( SELECT MAX(periodo)
    ->                     FROM tabla T2
    ->                     WHERE T2.periodo < T1.periodo) anterior
    ->   FROM tabla T1
    -> ) T;
+---------+----------+------------+
| periodo | anterior | diferencia |
+---------+----------+------------+
|  201601 |     NULL |       NULL |
|  201602 |   201601 |         -1 |
|  201603 |   201602 |         -1 |
|  201605 |   201603 |         -2 |
|  201608 |   201605 |         -3 |
|  201701 |   201608 |        -93 |
+---------+----------+------------+
6 rows in set (0.00 sec)

Observa el último de los casos, se ve el problema???

Haz la prueba y nos comentas.

Saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
2
Comentar
sin imagen de perfil

Restar perido

Publicado por Msp (8 intervenciones) el 08/06/2017 06:46:16
Muchas gracias por su ayuda mi estimado, asi es me olvide de especificar que los 4 primeros son del año y los dos sobrantes del mes..... en ese dilema ando ahora, habrá alguna manera de controlar la excesiva diferencia al cambiar de año? . Muchas gracias Nuevamente.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 806
Bronce
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

Restar perido

Publicado por leonardo_josue (1173 intervenciones) el 08/06/2017 15:52:42
Hola Msp:

De entrada yo te diría que estás equivocando la estrategia al tener campos INT si estás manejando información de MESES.

Podrías cambiar tu columna y manejarla como tipo DATE o DATETIME... poniendo por ejemplo, siempre el dia como 01... de tal suerte que en lugar de guardar 201607 almacenarías en la BD's '2016-07-01' o '2016-07-01 00:00:00'.

Si necesitas forzosamente mostrar sólo el año y el mes, entonces utilizas la función DATE_FORMAT para hacerlo:

1
2
3
4
5
6
7
mysql> SELECT NOW(), DATE_FORMAT(NOW(), '%Y%m');
+---------------------+----------------------------+
| NOW()               | DATE_FORMAT(NOW(), '%Y%m') |
+---------------------+----------------------------+
| 2017-06-08 08:42:56 | 201706                     |
+---------------------+----------------------------+
1 row in set (0.11 sec)

De esta manera, al manejar fechas, sería más fácil encontrar las diferencias utilizando las funciones propias de FECHA y HORA, usando por ejemplo la función TIMESTAMPDIFF:

1
2
3
4
5
6
7
mysql> SELECT TIMESTAMPDIFF(MONTH, '2017-01-01', '2016-08-01' ) DIFERENCIA;
+------------+
| DIFERENCIA |
+------------+
|         -5 |
+------------+
1 row in set (0.00 sec)

Ahora, si no quieres o no puedes cambiar el tipo de dato de la columna, tendrías que hacer conversiones para utilizar esta misma función, ¿Cómo se te ocurre que podrías hacerlo?

Saludos
Leo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar