Création d'un intervalle de dates à partir d'une seule date
Il arrive que les intervalles de temps ne soient pas stockés de manière explicite avec un début et une fin. Au lieu de cela, ils sont définis de manière implicite par un seul champ, l'horodatage de modification.
La table ci-dessous illustre une situation de ce genre, avec les taux de change définis pour plusieurs devises. Chaque modification du taux de change se trouve sur une ligne distincte, chacune avec un nouveau taux de conversion. La table contient par ailleurs des lignes aux dates vides qui correspondent au taux de conversion initial, avant la survenue de la première modification.
Currency | Change Date | Rate |
---|---|---|
EUR | - | 8.59 |
EUR | 28/01/2013 | 8.69 |
EUR | 15/02/2013 | 8.45 |
USD | - | 6.50 |
USD | 10/01/2013 | 6.56 |
USD | 03/02/2013 | 6.30 |
La table ci-dessus spécifie un ensemble d'intervalles qui ne se chevauchent pas, où la date de début est appelée Change Date et la date de fin est définie par le début de l'intervalle suivant. Cependant, comme la date de fin n'est pas stockée de manière explicite dans une colonne distincte, il est nécessaire de créer une colonne de ce type, afin que la nouvelle table devienne une liste d'intervalles.
Procédez comme suit :
- Créez une application et nommez-la.
- Ajoutez une nouvelle section de script dans l'éditeur de chargement de données.
- Ajoutez la table intégrée suivante. Assurez-vous que les dates figurant dans la colonne Change Date respectent le format de date local.
-
Décidez de la plage de temps que vous souhaitez utiliser. Le début de la plage doit être antérieur à la première date dans les données et la fin de la plage doit être postérieure à la dernière date.
Ajoutez ce qui suit au début du script :
Let vBeginTime = Num('1/1/2013'); Let vEndTime = Num('1/3/2013'); Let vEpsilon = Pow(2,-27);
-
Chargez les données source en remplaçant les dates vides par le début de la plage définie au point précédent. La date de modification doit être chargée sous "From Date".
Triez une première fois la table d'après la devise Currency, puis d'après la date de début "From Date" par ordre décroissant, de manière à placer les dates les plus récentes en haut de la liste.
Ajoutez ce qui suit après la table In_Rates :
Tmp_Rates: LOAD Currency, Rate, Date(If(IsNum([Change Date]), [Change Date], $(#vBeginTime))) as FromDate Resident In_Rates;
-
Exécutez un deuxième passage sur les données afin de calculer la date de fin "To Date". Si l'enregistrement actif dispose d'une devise différente de celle de l'enregistrement précédent, alors il s'agit du premier enregistrement d'une nouvelle devise (mais son dernier intervalle). Vous devez donc utiliser la fin de la plage définie à l'étape 1. S'il s'agit de la même devise, vous devez prendre la date de début "From Date" de l'enregistrement précédent, soustraire une petite fraction de temps et utiliser cette valeur comme date de fin "To Date" dans l'enregistrement actif.
Ajoutez ce qui suit après la table Tmp_Rates :
Rates: LOAD Currency, Rate, FromDate, Date(If( Currency=Peek('Currency'), Peek('FromDate') - $(#vEpsilon), $(#vEndTime) )) as ToDate Resident Tmp_Rates Order By Currency, FromDate Desc; Drop Table Tmp_Rates;
In_Rates:
LOAD * Inline [
Currency,Change Date,Rate
EUR,,8.59
EUR,28/01/2013,8.69
EUR,15/02/2013,8.45
USD,,6.50
USD,10/01/2013,6.56
USD,03/02/2013,6.30
];
Le script devrait avoir l'aspect suivant :
Let vBeginTime = Num('1/1/2013');
Let vEndTime = Num('1/3/2013');
Let vEpsilon = Pow(2,-27);
In_Rates:
LOAD * Inline [
Currency,Change Date,Rate
EUR,,8.59
EUR,28/01/2013,8.69
EUR,15/02/2013,8.45
USD,,6.50
USD,10/01/2013,6.56
USD,03/02/2013,6.30
];
Tmp_Rates:
LOAD Currency, Rate,
Date(If(IsNum([Change Date]), [Change Date], $(#vBeginTime))) as FromDate
Resident In_Rates;
Rates:
LOAD Currency, Rate, FromDate,
Date(If( Currency=Peek('Currency'),
Peek('FromDate') - $(#vEpsilon),
$(#vEndTime)
)) as ToDate
Resident Tmp_Rates
Order By Currency, FromDate Desc;
Drop Table Tmp_Rates;
Le script mettra à jour la table source de la manière suivante :
Currency | Rate | FromDate | ToDate |
---|---|---|---|
EUR | 8.45 | 15/02/2013 | vEndTime |
EUR | 8.69 | 28/01/2013 | 14/02/2013 23:59:59 |
EUR | 8.59 | vBeginTime | 28/01/2013 23:59:99 |
USD | 6.30 | 03/02/2013 | vEndTime |
USD | 6.56 | 10/01/2013 | 2/02/2013 23:59:59 |
USD | 6.50 | vBeginTime | 9/01/2013 23:59:59 |
Dans votre application, la table s'affiche de la façon suivante :
Currency | Rate | FromDate | ToDate |
---|---|---|---|
EUR | 8.45 | 15/02/2013 | 01/03/2013 |
EUR | 8.69 | 28/01/2013 | 14/02/2013 |
EUR | 8.59 | 01/01/2013 | 28/01/2013 |
USD | 6.30 | 03/02/2013 | 01/03/2013 |
USD | 6.56 | 10/01/2013 | 2/02/2013 |
USD | 6.50 | 01/01/2013 | 9/01/2013 |
Cette table peut ensuite servir dans un comparatif à une date existante à l'aide de la méthode Intervalmatch.