Ir al contenido



Foto

Contar días de diferencia en un loop?


  • Por favor identifícate para responder
6 respuestas en este tema

#1 Pratasvenska

Pratasvenska

    Member

  • Miembros
  • PipPip
  • 37 mensajes
  • LocationSuecia

Escrito 19 enero 2015 - 10:27

Buen día,

Espero puedan ayudarme, que soy un poco (muy) malo con las funciones en SQL. Tengo una tabla donde almaceno una fecha (datetime) y un estado (varchar) de 3 posibles (in/out/end), por ejemplo:

FECHA/ESTADO
2015-01-01 / In
2015-01-02 / Out
2015-01-03 / In
2015-01-06 / End

Cómo podría hacer para saber el numero de días que el objeto estuvo "in"? En este caso el procedimiento sería:
1. Encontrar primer fecha de estado "in", encontrar primer fecha de estado "out" y restar = 1 día
2. Encontrar siguiente fecha de estado "in", encontrar siguiente fecha de estado "end" y restar = 3 días.
3. Total días "in" = 4

*Si el día in es el mismo que out/end aún asi cuenta como 1 día.
*Pueden existir mas pares de "in" y "out" antes del "end" final.

Espero haberme dado a entender? Muchas gracias y un saludo.
  • 0

#2 Nikolas

Nikolas

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 591 mensajes
  • LocationMar del Plata / Bs As / Argentina

Escrito 20 enero 2015 - 09:49

yo lo haria con un SP, suponiendo que los datos siempre van a ser validos.

  • 0

#3 Sergio

Sergio

    Advanced Member

  • Moderadores
  • PipPipPip
  • 1.092 mensajes
  • LocationMurcia, España

Escrito 20 enero 2015 - 02:02

En FireBird tienes DaysBetween(Fecha1, Fecha2) y supongo que en SQLServer habrá algún sustituto, o en otras ocasiones te vale con restar las fechas, ya que la parte entra es el numero de dias desde el inicio del calendario gregoriano (creo) y la fraccionaria la porcion de dia transcurrido, si es asi en SQLServer tambien te serviria Round(Fecha2 - Fecha1).
  • 0

#4 Pratasvenska

Pratasvenska

    Member

  • Miembros
  • PipPip
  • 37 mensajes
  • LocationSuecia

Escrito 16 octubre 2015 - 05:40

volviendo a este tema despues de muchos meses (en aquel entonces bastó con programarlo en delphi):


delphi
  1. function DiasDif: String;
  2. var
  3. inDate, outDate: TDateTime;
  4. c, r : integer;
  5. begin
  6. c := 0;
  7. r := 0;
  8. Result := '';
  9. with Dataset do
  10. begin
  11. if First then
  12. repeat
  13. inDate := fields['DATUM'].AsDate;
  14. if Next then
  15. begin
  16. if (fields['TYP'].AsUchar = 'U') or (fields['TYP'].AsUchar = 'X') then
  17. begin
  18. outDate := fields['DATUM'].AsDate;
  19. c := DaysBetween(inDate, outDate);
  20. end;
  21. end
  22. else
  23. c := DaysBetween(inDate, Now);
  24.  
  25. r := r + c;
  26. until not Next;
  27. Result := IntToStr(r);
  28. end;
  29. end;

Algún maestro de SQL que me pudiera ayudar a "traducir" esta funcion a SQL server 2005 y posterior?? Los campos usados DATUM y TYP estan en la misma tabla.

 

Muchas gracias de antemano.


  • 1

#5 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.254 mensajes
  • LocationRepública Dominicana

Escrito 16 octubre 2015 - 08:12

Me imagino que hay algun id o campo en comun, sería algo así:
 
 

sql
  1. SELECT DATEDIFF(DATE, MAX( CASE WHEN tipo = "out" THEN fecha END ) ,
  2. MIN( CASE WHEN tipo = "in" THEN fecha END ) ) AS Duration
  3. FROM fechas GROUP BY id


Nos comentas.

Saludos
  • 0

#6 Pratasvenska

Pratasvenska

    Member

  • Miembros
  • PipPip
  • 37 mensajes
  • LocationSuecia

Escrito 19 octubre 2015 - 12:22

Me imagino que hay algun id o campo en comun, sería algo así:
 
 


sql
  1. SELECT DATEDIFF(DATE, MAX( CASE WHEN tipo = "out" THEN fecha END ) ,
  2. MIN( CASE WHEN tipo = "in" THEN fecha END ) ) AS Duration
  3. FROM fechas GROUP BY id

Nos comentas.

Saludos

 

Hola, gracias por la respuesta.. A ésto ya había llegado, como bien dices, hay un campo en común (TYP), que puede ser "in", "out" y "end". la duda que tengo es cómo hacer un stored procedure que incluya un loop, la explicación completa está en el primer post del hilo.

 

Un saludo!


  • 0

#7 cram

cram

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 824 mensajes
  • LocationMisiones, Argentina

Escrito 22 octubre 2015 - 09:42

Si siempre son pares In-Out o In-End, supongo que habrá un campo para seleccionar ese grupo de E/S con algún código o algo, por lo que no es necesario tener un campo que indique cuando es In y cuando es Out o End.

Bastaría con tomar el subconjunto de días y ordenarlos en orden creciente, su cantidad debería ser par siempre, caso contrario sería un error o condición de no poder precisar el tiempo total de "In". Luego dentro del ciclo, se suma la diferencia existente entre dos días contiguos, haciendo valer uno cuando la diferencia sea cero o el valor de la diferencia cuando sea mayor que 0. Esa sumatoria será el tiempo que estuvo "In", puesto que el primer día es In y el segundo Out o End.

 

Saludos


  • 0