Datediff non funziona bene nel mio caso?

mercoledì 09 luglio 2008 - 16.40

alkes83 Profilo | Junior Member

Ciao a tutti, ho un problema in SQL.

Devo calcolare il ritardo di un treno tra due campi che hanno formato "Ora", il ritardo viene calcolato come arrivo Reale - Teorico, quindi la differenza tra i due campi è riempie un terzo campo chiamato Delta. Il problema sorge quando nel caso di arrivo teorico ad esempio alle 23.00 il treno arrivi alle 01.00, il risulato dovrebbe essere di 120 minuti di ritardo, il realtà mi dice che è il anticipo di 1320 minuti. Be allora il voglio dirgli nel caso di anticipo superiore a 240 minuti aggiungigli 1440 minuti. Che cosa mi cosigliate?

Attualmente utilizzo questa stringa, dove:

MAD t : arrivo teorico
MAD r : arrivo reale

IIf([MAD t]-[MAD r]<0,DateDiff("n",[MAD t],[MAD r]),IIf(DateDiff("n",[MAD r],[MAD t])>240,-DateDiff("n",[MAD r],[MAD t])+1440,-DateDiff("n",[MAD r],[MAD t]))) AS Delta_MAD

Ma nn ottengo quello che voglio.

Brainkiller Profilo | Guru

>Devo calcolare il ritardo di un treno tra due campi che hanno
>formato "Ora", il ritardo viene calcolato come arrivo Reale -
>Teorico, quindi la differenza tra i due campi è riempie un terzo
>campo chiamato Delta.

Se i treni sono quelli di Trenitalia saranno sempre in ritardo quindi il problema è grave

>Il problema sorge quando nel caso di arrivo
>teorico ad esempio alle 23.00 il treno arrivi alle 01.00, il
>risulato dovrebbe essere di 120 minuti di ritardo, il realtà
>mi dice che è il anticipo di 1320 minuti. Be allora il voglio
>dirgli nel caso di anticipo superiore a 240 minuti aggiungigli
>1440 minuti. Che cosa mi cosigliate?

Esatto, perchè bisogna gestire il cambio di data e nella colonna non è immagazzinata la data...

Che Database stai utilizzando ?

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/

alkes83 Profilo | Junior Member

Non posso cambiare il formato delle colonne, posso utilizzare solo quello che ho a diposizione.

Cmq sto utilizzando Access.

p.s. nn sono treni di Trenitalia

Dainesi Profilo | Senior Member

Se il campo includesse anche la data sarebbe immediata la soluzione, se invece contiene solo l'ora (grave mancanza !!) la tua formula si potrebbe ottimizzare così:

MAD t : arrivo teorico
MAD r : arrivo reale

'Da così
IIf([MAD t]-[MAD r]<0,DateDiff("n",[MAD t],[MAD r]),IIf(DateDiff("n",[MAD r],[MAD t])>240,-DateDiff("n",[MAD r],[MAD t])+1440,-DateDiff("n",[MAD r],[MAD t]))) AS Delta_MAD

'A così:
IIf([MAD t]-[MAD r]<0,DateDiff("n",[MAD t],[MAD r]), Hour([MAD r]) * 60 + Minute([MAD r]) + DateDiff("n",[MAD t], "23:59:59"))AS Delta_MAD

Brainkiller Profilo | Guru

>Non posso cambiare il formato delle colonne, posso utilizzare
>solo quello che ho a diposizione.
>Cmq sto utilizzando Access.

Eh eh, se no avevamo molte più soluzioni. Perchè purtroppo in Access spesso bisogna concatenare tutte le funzioni come hai fatto tu in una riga e diventano illeggibili.

Io farei così, faccio un IF e vedo se l'ora di arrivo effettiva è maggiore di quella teorica e cade nel giorno seguente ossia è maggiore di 00.00 faccio un tipo di calcolo cioè tipo (24 - 23) + la spezzatura dalle 00.00 in poi. Se no utilizzo il calcolo tradizionale con il DateDiff.
Ciao

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/

alkes83 Profilo | Junior Member

Ciao Dainesi,

ho provato la tua stringa, ma quando il treno arriva in anticipo la cella è vuota, come mai?

Dainesi Profilo | Senior Member

Dunque ... riepiloghiamo:

Se Teorico > Reale si verifica in due casi:
- in anticipo: Teorico 16:50 Reale 16:40 ---> 10' di Anticipo
- in ritardo: Teorico 23:40 Reale 00:30 ---> 50' di Ritardo

Se Teorico < Reale si verifica in due casi:
- in anticipo: Teorico 16:40 Reale 16:50 ---> 10' di Ritardo
- in ritardo: Teorico 00:30 Reale 23:40 ---> 50' di Anticipo

Purtroppo se vogliamo avere anche degli anticipi dobbiamo fare degli assunti, ovvero che lo scostamento non può essere superiore alle 12 ore (con le ferrovie chi può mai assicurarlo ....) e quindi complicheremo la nostra formula:

MAD t : arrivo teorico
MAD r : arrivo reale

'Da così
IIf([MAD t]-[MAD r]<0,DateDiff("n",[MAD t],[MAD r]),IIf(DateDiff("n",[MAD r],[MAD t])>240,-DateDiff("n",[MAD r],[MAD t])+1440,-DateDiff("n",[MAD r],[MAD t]))) AS Delta_MAD

'A così:
IIf(IIf([MAD t]-[MAD r]<0,DateDiff("n",[MAD t],[MAD r]),Hour([MAD r])*60+Minute([MAD r])+DateDiff("n",[MAD t],"23:59:59"))>720,IIf([MAD t]-[MAD r]<0,DateDiff("n",[MAD t],[MAD r]),Hour([MAD r])*60+Minute([MAD r])+DateDiff("n",[MAD t],"23:59:59"))-1440,IIf([MAD t]-[MAD r]<0,DateDiff("n",[MAD t],[MAD r]),Hour([MAD r])*60+Minute([MAD r])+DateDiff("n",[MAD t],"23:59:59"))) AS Delta_MAD


alkes83 Profilo | Junior Member

Ciao Dainesi,

sei un grande, funziona!!!!!!!

L'unica cosa che non capisco però, è che quando il treno arriva puntuale, cioè teorico uguale a reale, mi da un anticipo di minuto. Perchè?

Intanto grazie tantissimo.

Dainesi Profilo | Senior Member

Perché confrontiamo con le 23:59:59. Evidentemente il tuo dato orario riporta solo ora e data e non i secondi. D'altronde è l'unico modo per comprendere anticipi e ritardi.
Confrontando rimangono fuori 59 secondi !!!

Vediamo insieme:

IIf(IIf([MAD t]-[MAD r]<0,DateDiff("n",[MAD t],[MAD r]),Hour([MAD r])*60+Minute([MAD r])+DateDiff("n",[MAD t],"23:59:59"))>720,IIf([MAD t]-[MAD r]<0,DateDiff("n",[MAD t],[MAD r]),Hour([MAD r])*60+Minute([MAD r])+DateDiff("n",[MAD t],"23:59:59"))-1440,IIf([MAD t]-[MAD r]<0,DateDiff("n",[MAD t],[MAD r]),Hour([MAD r])*60+Minute([MAD r])+DateDiff("n",[MAD t],"23:59:59"))) AS Delta_MAD

Orario Reale 10:30 orario teorico 10:30

IIf(IIf([10:30]-[10:30]<0,DateDiff("n",[10:30],[10:30]),Hour([10:30])*60+Minute([10:30])+DateDiff("n",[10:30],"23:59:59"))>720,IIf([10:30]-[10:30]<0,DateDiff("n",[10:30],[10:30]),Hour([10:30])*60+Minute([10:30])+DateDiff("n",[10:30],"23:59:59"))-1440,IIf([10:30]-[10:30]<0,DateDiff("n",[10:30],[10:30]),Hour([10:30])*60+Minute([10:30])+DateDiff("n",[10:30],"23:59:59"))) AS Delta_MAD

che sintetizzando diventa

IIf(IIf(0<0,0),630+809)>720,IIf(0<0,0,630+809)-1440,IIf(0<0,0,630+809)) AS Delta_MAD
..
IIf(1439>720,1439-1440,1439) AS Delta_MAD
..
-1 AS Delta_MAD

e quindi avendo posto in DateDiff il parametro di confronto "n" (i minuti) e la differenza non tiene conto dei secondi e quindi ti porta 1 minuto di differenza. Per risolvere isoliamo il caso in cui i due orari coincidono:

IIf([MAD t]=[MAD r],0,IIf(IIf([MAD t]-[MAD r]<0,DateDiff("n",[MAD t],[MAD r]),Hour([MAD r])*60+Minute([MAD r])+DateDiff("n",[MAD t],"23:59:59"))>720,IIf([MAD t]-[MAD r]<0,DateDiff("n",[MAD t],[MAD r]),Hour([MAD r])*60+Minute([MAD r])+DateDiff("n",[MAD t],"23:59:59"))-1440,IIf([MAD t]-[MAD r]<0,DateDiff("n",[MAD t],[MAD r]),Hour([MAD r])*60+Minute([MAD r])+DateDiff("n",[MAD t],"23:59:59")))) AS Delta_MA

alkes83 Profilo | Junior Member

Grazie, veramente grazie, mi hai tirato fuori da molti casini.

Ciao

Dainesi Profilo | Senior Member

Non c'è di che.

Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5