Contar días de diferencia en un loop?
#1
Escrito 19 enero 2015 - 10:27
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.
#2
Escrito 20 enero 2015 - 09:49
#3
Escrito 20 enero 2015 - 02:02
#4
Escrito 16 octubre 2015 - 05:40
volviendo a este tema despues de muchos meses (en aquel entonces bastó con programarlo en delphi):
function DiasDif: String; var inDate, outDate: TDateTime; c, r : integer; begin c := 0; r := 0; Result := ''; with Dataset do begin if First then repeat inDate := fields['DATUM'].AsDate; if Next then begin if (fields['TYP'].AsUchar = 'U') or (fields['TYP'].AsUchar = 'X') then begin outDate := fields['DATUM'].AsDate; c := DaysBetween(inDate, outDate); end; end else c := DaysBetween(inDate, Now); r := r + c; until not Next; Result := IntToStr(r); end; 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.
#5
Escrito 16 octubre 2015 - 08:12
SELECT DATEDIFF(DATE, MAX( CASE WHEN tipo = "out" THEN fecha END ) , MIN( CASE WHEN tipo = "in" THEN fecha END ) ) AS Duration FROM fechas GROUP BY id
Nos comentas.
Saludos
#6
Escrito 19 octubre 2015 - 12:22
Me imagino que hay algun id o campo en comun, sería algo así:
sql
SELECT DATEDIFF(DATE, MAX( CASE WHEN tipo = "out" THEN fecha END ) , MIN( CASE WHEN tipo = "in" THEN fecha END ) ) AS Duration 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!
#7
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