根据一个日期创建日期间隔

有时候,存储的时间间隔不含明确的开始和结束日期。相反,它们只由一个字段暗示 – 更改时间戳。

如下表所示,您可以拥有多种货币的货币汇率。每一种货币汇率变化都位于自己的行中;每一行都包含新的兑换率。此外,该表包含与进行第一次更换之前原始兑换率对应的空日期的行。

货币汇率
货币 更改日期 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

该表定义了一组非重叠间隔,其开始日期称为“Change Date”,结束日期由以下间隔的开始所定义。但是,由于结束日期不是明确地存储在自己的列中,因此我们需要创建这样的列,以使新表将成为间隔的列表。

在此脚本示例中,通过内联加载创建表格 In_Rates。确保 Change Date 列中日期的格式与本地日期格式相同。

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 ];

执行以下操作:

  1. 确定您想要使用的时间范围。时间范围的开始必须为数据中第一个日期之前,时间范围的结束必须为最后一个日期之后。

    Let vBeginTime = Num('1/1/2013');
    Let vEndTime = Num('1/3/2013');
    Let vEpsilon = Pow(2,-27);
  1. 加载源数据,但将空日期更改为在上一个项目符号中所定义的时间范围的开始。应加载更改日期作为“From Date”。

    首先根据 Currency 对表格进行排序,然后根据“From Date”以降序顺序对表格进行排序,使最新日期位于表格顶部。

    Tmp_Rates:
    LOAD Currency, Rate,
    Date(If(IsNum([Change Date]), [Change Date], $(#vBeginTime))) as FromDate
    Resident In_Rates;
  2. 运行第二个通过数据,以计算“To Date”。如果当前记录拥有与之前记录不同的货币,则该记录是新货币的第一个记录(但其间隔为最后一个间隔),因此您应使用在步骤 1 中所定义的时间范围的结束日期。如果两个记录的货币相同,则应使用前一个记录的“From Date”,减去一个小的时间数目,然后将此值用作当前记录的“To Date”。

    Rates:
    LOAD Currency, Rate, FromDate,
    Date(If( Currency=Peek('Currency'),
    Peek('FromDate') - $(#vEpsilon),
    $(#vEndTime)
    )) as ToDate
    Resident Tmp_Rates
    Order By Currency, FromDate Desc;
  3. 删除输入表格和临时表格。

    Drop Table Tmp_Rates;

下面列出的脚本将会按以下方式更新源表:

更新的源表格
货币 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

当运行脚本时,您将会获得已正确列出间隔的表格。使用数据模型查看器的预览部分查看生成的表格。

数据预览
货币 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

随后,在使用 Intervalmatch 方法与现有日期进行比较时可以使用该表。

Example:  

完整 Qlik Sense 脚本应如下所示:

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;