SQL - Consulta Calculo de Tiempo

 
Vista:
Imágen de perfil de IvanRino
Val: 6
Ha aumentado su posición en 4 puestos en SQL (en relación al último mes)
Gráfica de SQL

Consulta Calculo de Tiempo

Publicado por IvanRino (3 intervenciones) el 26/02/2019 17:59:52
Hola Señores.
Tengo una necesidad urgente y requiero de su colaboración:

Tengo una tabla donde existen ordenes de trabajo por estado (Creado, Asignado, En progreso, Resuelto , Completado) y a cada estado existe una fecha en la que paso a ese estado y un responsable que lo realizo:

OT ESTADO FECHA RESPONSABLE
1 OT7367 WAPPR 22/01/2019 06:34:35 a.m. ECM6967D
2 OT7367 PENDING 22/01/2019 06:46:55 a.m. ICM1743A
3 OT7367 INPROG 22/01/2019 10:34:50 a.m. ICM1743A
4 OT7367 CLOSE 22/01/2019 10:36:02 a.m. ICM1743A


Requiero poder calcular el tiempo que duro en cada estado la diferencia de la fecha de la linea 2 menos la fecha de la linea 1 es el tiempo en el estado WAPPR y quien lo modifico fue ECM6967D, obviamente las fechas deben estar organizadas de forma ascendente (mas antigua a mas reciente).

Finalmente requiero tener algo similar a:

OT ESTADO TIEMPO_DIAS RESPONSABLE
1 OT7367 WAPPR 0,008564815 ECM6967D


Quedo Pendiente de su pronta respuesta.

De antemano gracias por el tiempo
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
Imágen de perfil de Isaias
Val: 2.542
Oro
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

Consulta Calculo de Tiempo

Publicado por Isaias (1921 intervenciones) el 26/02/2019 23:09:17
Ivan

Espero no tome muy a pecho mi comentario, en los foros no hay nada URGENTE que resolver, todo lleva su tiempo

Segundo, usted NO menciona que motor de base de datos esta utilizando.

Entre mas rápido nos comente al respecto, tal vez sea mas RÁPIDA la respuesta
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
Imágen de perfil de Ivan
Val: 6
Ha aumentado su posición en 4 puestos en SQL (en relación al último mes)
Gráfica de SQL

Consulta Calculo de Tiempo

Publicado por Ivan (3 intervenciones) el 27/02/2019 15:37:02
Gracias por el comentario. Si tienes razón la palabra URGENTE en un foro sobra.... y gracias por tomarte el tiempo en leer mi inquietud. Efectivamente estoy en una base de Oracle trabajando en los cálculos de unos tiempos. Ya me dieron la orientación para trabajar con una funcion utilizando cursores y apuntadores para poder guardar las fechas de manera temporar y recorrer los registros.... Es algo complicado de entender... pero me ayudo para la necesidad que tengo. La voy a poner en el post por si alguien la comprende mejor y posiblemente simplificarla:

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
29
30
31
32
33
CREATE OR REPLACE FUNCTION FUN_TIME_IDLE
(
  P_OT IN VARCHAR2
) RETURN NUMBER AS
 
CURSOR C_STATUS IS
SELECT CHANGEDATE,WONUM,STATUS,CHANGEBY
FROM maximo.WOSTATUS
WHERE WONUM = P_OT
ORDER BY CHANGEDATE DESC;
 
 r_status c_status%ROWTYPE;
 acum number:=0;
 delta number:=0;
 prev date:=null;
 curr date:=null;
 
BEGIN
 
  OPEN c_status;
 
  LOOP
    FETCH  c_status  INTO r_status;
    EXIT WHEN c_status%NOTFOUND;
    prev:=curr;
    curr:=r_status.CHANGEDATE;
    delta:=prev - curr;
    if r_status.STATUS in ('PENDING','COMP') then
      acum:=acum + delta;
    end if;
 
  END LOOP;
  CLOSE c_status;
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

Consulta Calculo de Tiempo

Publicado por leonardo_josue (1173 intervenciones) el 26/02/2019 23:11:42
Hola IvanRino:

Primero, no nos dices con qué Base de Datos estás trabajando y así resulta complicado darte una respuesta puntual, sobre todo porque el
manejo de fechas es muy distinto para cada DBMS...

Segundo, no nos dices qué es lo que intentaste hacer, porque supongo que al menos intentaste hacer la consulta por tu cuenta, entonces, siempre que publiques una pregunta debes de incluir el código SQL que intentaste hacer, no importa si contiene errores o si no funciona como quieres. Si fuera el caso, entonces incluyes también los códigos de error que te está arrojando el DBMS o comentas qué es lo que está funcionando mal en la consulta.

Tercero, cuidado con pedir una "pronta respuesta". Esta expresión es utilizada cuando pides alguna cosa a alguien que está "obligado" a hacer las cosas... puede no ser tu intención, pero en un ambiente donde lo que se lee puede interpretarse de maneras erróneas, te sugiero tener cuidado con lo escribes ("quedo pendiende de su respuesta" quedaría mejor ¿no crees?)

finalmente, el "truco" para tu consulta es empatar un registro con su siguiente registro, es decir, el 1 con el 2, el 2 con el 3 y así sucesivamente... tienes muchas formas para hacer esto, la más "simple" sería con subconsulta. Aquí pongo un ejemplo de cómo podrías hacerlo en MySQL:

Supongamos que tienes esta tabla;

1
2
3
4
5
6
7
8
9
10
11
12
mysql> SELECT * FROM tabla;
+------+-------------+
| id   | descripcion |
+------+-------------+
|    1 | uno         |
|    2 | dos         |
|    3 | tres        |
|    4 | cuatro      |
|    6 | seis        |
|   10 | diez        |
+------+-------------+
6 rows in set (0.00 sec)

Entonces para empatar cada registro con su "siguiente" una forma podría ser así:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql> SELECT T1.*, ( SELECT id
    ->                FROM tabla T2
    ->                WHERE T2.id > T1.id
    ->                ORDER BY id
    ->                LIMIT 1) siguiente_id
    -> FROM tabla T1;
+------+-------------+--------------+
| id   | descripcion | siguiente_id |
+------+-------------+--------------+
|    1 | uno         |            2 |
|    2 | dos         |            3 |
|    3 | tres        |            4 |
|    4 | cuatro      |            6 |
|    6 | seis        |           10 |
|   10 | diez        |         NULL |
+------+-------------+--------------+
6 rows in set (0.00 sec)

Esta no es la única forma (y puede que tampoco sea la mejor) pero la idea sería así... entonces, si quisieras sacar la diferencia entre los ID's, podrías ponerlo en otra subconsulta:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
mysql> SELECT id, siguiente_id, siguiente_id - id diferencia, descripcion
    -> FROM
    -> (SELECT T1.*, ( SELECT id
    ->    FROM tabla T2
    ->    WHERE T2.id > T1.id
    ->    ORDER BY id
    ->    LIMIT 1) siguiente_id
    -> FROM tabla T1 ) T;
+------+--------------+------------+-------------+
| id   | siguiente_id | diferencia | descripcion |
+------+--------------+------------+-------------+
|    1 |            2 |          1 | uno         |
|    2 |            3 |          1 | dos         |
|    3 |            4 |          1 | tres        |
|    4 |            6 |          2 | cuatro      |
|    6 |           10 |          4 | seis        |
|   10 |         NULL |       NULL | diez        |
+------+--------------+------------+-------------+
6 rows in set (0.00 sec)

¿Se entiende?

Haz la prueba y nos comentas.

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
1
Comentar
Imágen de perfil de Ivan
Val: 6
Ha aumentado su posición en 4 puestos en SQL (en relación al último mes)
Gráfica de SQL

Consulta Calculo de Tiempo

Publicado por Ivan (3 intervenciones) el 27/02/2019 15:49:29
Leonardo_Josue Cordial Saludo.

Gracias por tus observaciones y las tendré muy en cuenta para participar en los Foros:

1. Efectivamente estoy trabajando en una base de datos de ORACLE replica de una base de datos de la empresa donde laboro donde estan todas las tablas y tengo que crear las consultas adecuadas para sacar la información y mostrarla en forma de indicadores.

2. Con Referencia a lo que intente hacer... he hecho muchos intentos de tratar de trasponer los datos de filtrarlos y extraer el valor correspondiente, pero los resultados no son como los necesitaba. Finalmente un compañero de la oficina me colaboro con una funcion que recorre los registros y los compara haciendo la resta correspondiente aplicando solo a ciertos campos expecificos. Adjunto la función que me ayudao a tal fin.

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
29
30
31
32
33
CREATE OR REPLACE FUNCTION FUN_TIME_IDLE
(
  P_OT IN VARCHAR2
) RETURN NUMBER AS
 
CURSOR C_STATUS IS
SELECT CHANGEDATE,WONUM,STATUS,CHANGEBY
FROM maximo.WOSTATUS
WHERE WONUM = P_OT
ORDER BY CHANGEDATE DESC;
 
 r_status c_status%ROWTYPE;
 acum number:=0;
 delta number:=0;
 prev date:=null;
 curr date:=null;
 
BEGIN
 
  OPEN c_status;
 
  LOOP
    FETCH  c_status  INTO r_status;
    EXIT WHEN c_status%NOTFOUND;
    prev:=curr;
    curr:=r_status.CHANGEDATE;
    delta:=prev - curr;
    if r_status.STATUS in ('PENDING','COMP') then
      acum:=acum + delta;
    end if;
 
  END LOOP;
  CLOSE c_status;

3. Tienes razón con los terminos que se manejan en los foros y pueden ser mal interpretados, no era para nada mi intensión pero lo tendre en cuenta para futuras participaciones.

4. Gracias por la idea que me aportas voy a intentar abordar el problema por el lado que me explicas y les estaré comentando mi experiencia.

De antemano gracias por el tiempo que destinan a responder estos foros y a compartir el conocimiento.
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
Imágen de perfil de Vega
Val: 187
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

Consulta Calculo de Tiempo

Publicado por Vega (73 intervenciones) el 12/03/2019 00:08:39
esta es para SQL Server, por si te dá una pista. No tengo Oracle a mano pero sé que también soporta las funciones LEAD() y LAG()
1
2
3
4
5
6
7
8
9
10
11
12
13
with data as (
select id = 1 , Ot =  'OT7367', estado =   'WAPPR'	, fecha =	cast('22/01/2019 06:34:35' as datetime), responsable = 'ECM6967D'union all
select id = 2, 'OT7367',  'PENDING' ,							cast('22/01/2019 06:46:55' as datetime), 'ICM1743A'										 union all
select id = 3, 'OT7367',  'INPROG'  ,							cast('22/01/2019 10:34:50' as datetime), 'ICM1743A'										 union all
select id = 4, 'OT7367',  'CLOSE'	,							cast('22/01/2019 10:36:02' as datetime), 'ICM1743A'
)
 
select		*
,lead(responsable,1) over (partition by ot order by fecha asc)
 
,			datediff(day, fecha, lead(fecha,1) over (partition by ot order by fecha asc))
from		data
order by	fecha asc
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