Создание интервала дат из одиночной даты
Иногда у интервалов времени нет четко выраженного начала и конца. Они подразумеваются только одним полем — меткой времени изменения.
Это может быть как в таблице ниже, где для различных валют указаны курсы валют. Каждый курс валют указан в отдельной строке, каждый — с новым обменным курсом. Также в таблице есть строки с пустыми датами, соответствующими исходному обменному курсу, который существовал до первого изменения.
| Currency (Валюта) | Дата изменения | Курс |
|---|---|---|
| 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 |
Таблица выше определяет набор неперекрывающихся интервалов, где начальные данные называются Change Date, а конечная дата определяется началом следующего интервала. Но поскольку дата конца хранится в своем столбце неявно, необходимо создать такой столбец, чтобы новая таблица стала списком интервалов.
Выполните следующие действия.
- Создайте новое приложение и дайте ему имя.
- Добавьте новый раздел скрипта в Редакторе загрузки данных.
- Добавьте следующую встроенную таблицу. Убедитесь, что даты в столбце Change Date указаны в том же формате, что и локальный формат даты.
-
Определите временной диапазон, с которым вы хотели бы работать. Начало диапазона должно предшествовать первой дате в данных, а конец диапазона должен быть после последней даты.
Добавьте следующее в начало вашего скрипта:
Let vBeginTime = Num('1/1/2013'); Let vEndTime = Num('1/3/2013'); Let vEpsilon = Pow(2,-27); -
Загрузите исходные данные, но измените пустые даты на начало диапазона, определенного в предыдущем маркере. Дата изменения должна быть загружена как "From Date".
Отсортируйте таблицу сначала по Currency, затем по "From Date" в убывающем порядке, чтобы самые новые даты были сверху.
Добавьте следующее после таблицы In_Rates:
Tmp_Rates: LOAD Currency, Rate, Date(If(IsNum([Change Date]), [Change Date], $(#vBeginTime))) as FromDate Resident In_Rates; -
Выполните второй проход по данным, где вычисляется "To Date". Если валюта текущей записи отличается от валюты предыдущей, то это первая запись новой валюты (но ее последнего интервала), поэтому следует использовать конец диапазона, определенного в шаге 1. Если валюта та же, следует взять "From Date" из предыдущей записи, вычесть небольшое количество времени и использовать это значение как "To Date" в текущей записи.
Добавьте следующее после таблицы 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
];
Скрипт должен выглядеть следующим образом:
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;Скрипт обновит исходную таблицу следующим образом:
| Currency (Валюта) | Курс | Дата начала | Дата окончания |
|---|---|---|---|
| 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 |
В вашем приложении таблица выглядит следующим образом:
| Currency (Валюта) | Курс | FromDate | К дате |
|---|---|---|---|
| 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 | 02.03.2013 | 03.01.2013 |
| USD | 6,56 | 01.10.2013 | 2/02/2013 |
| USD | 6,50 | 01.01.2013 | 9/01/2013 |
Впоследствии эту таблицу можно использовать при сравнении с существующей датой с помощью функции Intervalmatch.