事实表变更

时间:2015-10-21 04:04:26

标签: sql database etl data-warehouse business-intelligence

CONTEXT

我正在尝试创建销售事实表。 每行代表客户订单中的产品。 在其他领域中,我有以下3个特定领域:

  • purchasing_price
  • selling_price
  • 余量

问题

在我们公司,当我们销售产品时,我并不确切知道购买价格,因为我将在稍后支付此产品,购买价格将基于付款日的汇率。 我通常知道订单日期后1周到2个月之间的实际购买价格。 事实上,我们公司得到了一项安排,允许我们从下个月的第15个月开始向供应商付款,从我们从供应商那里收到产品的那个月开始。 由于我们在不同国家有供应商,汇率会引发一些问题。

结果等待

我必须生成2份月度报告和1份年度报告: - 根据订单日期的汇率,每月1日报告1次 - 根据付款日期的汇率(即当前日期的汇率,因为我们每个月的15日向供应商付款),每月15日的1份报告 - 根据付款日期的汇率(有时可能是订单日期后2个月)的1份年度报告

示例

  1. 我于7月3日订购了产品。
  2. 此产品仅于8月7日交付
  3. 然后我会根据这个日期的汇率在9月15日支付产品。
  4. 到目前为止,我只找到了3个解决方案:

    1. a)在事实表和2个字段中创建1行: real_purchasing_price (等于0)和 temporary_purchasing_price (这将自动相等)根据订单日期的汇率购买价格)。 b)一旦我支付了产品,我就知道正确的汇率,因此我可以根据付款汇率更新此行,并使用购买价格 real_purchasing_price

    2. a)根据订单日期的汇率,使用 purchase_price 在事实表中创建1行。 b)一旦我支付了产品,我知道正确的汇率因此我可以在事实表中创建一个与第一个几乎相似的新行,但这次是基于汇率的 purchase_price 付款日期。

    3. a)根据订单日期的汇率,使用 purchase_price 在事实表中创建一行 b)一旦我支付了产品,我就知道正确的汇率,因此我可以更新这一行并将 purchase_price 替换为基于正确汇率的那一行。

    4. 第四种解决方案属于你。

      谢谢你的帮助。 不要犹豫,向我询问更多细节。

      祝你有个美好的一天,

3 个答案:

答案 0 :(得分:1)

我实际上选择使用货币表并添加一个字段payment_date,它允许我在货币表中将事实表的每一行与正确的汇率相匹配。

尽管如此,我必须更新事实表的每一行,以便在我知道后添加payment_date。

到目前为止,我找不到更好的解决方案。

大家好。

答案 1 :(得分:0)

我假设对于购买价格,你有一个固定的组件和另一个可变的组件,取决于汇率。 (比如p * x,其中x是汇率)

我建议创建一个新的事实表,例如exchange_rates,其中包含不同国家/地区的汇率和时间戳。现在,事实表中的列purchasing_price应该是来自该国家/地区的exchange_rates表的加入结果。

让我们说current_values栏保持汇率。

    EXCHANGE_RATES
    +-------------+---------------+---------------+-----------+
    | EXCHANGE_ID | EXCHANGE_NAME | CURRENT_VALUE | TIMESTAMP |
    +-------------+---------------+---------------+-----------+
    |           1 | JAPAN         |           100 |  20151021 |
    +-------------+---------------+---------------+-----------+     

在填充购买价格时,请使用EXCHANGE_RATES中的此值来获取正确的值。

    ORDER_DETAIL_FACT       
    +----------+---------+------------------+---------------+--------+
    | ORDER_ID | PRODUCT | PURCHASING_PRICE | SELLING_PRICE | MARGIN |
    +----------+---------+------------------+---------------+--------+
    |      101 |      11 | 50*100           |          6000 |   1000 |
    +----------+---------+------------------+---------------+--------+

如果您需要有关其实施的帮助,请告诉我。

答案 2 :(得分:0)

您的订单似乎经历了三个阶段:

  • <强>有序

  • <强>递送

  • 购买价格已知

一种数据仓库设计方法是不变性(仅插入,不进行更新)。

这种方法可以为您的订单创建三个事实记录

订购活动

带有属性

 orderId, productId, orderDate  and sellingPrice

已发送活动

 orderId, DeliveryDate, 

请注意,订单和交货记录与OrderId唯一相关(在每个订单只有一个产品的简化假设下)。

这两个事件都存储在单独的事实表或公共事件表中 - 它取决于您的完整属性定义。

购买价格存储在具有属性

的单独表格中
productId, entryDate, validFromDate, ValidToDate, purchasingPrice

根据您在下个月15日(entryDate)的规则填写表格,其中包含前一个月的有效期。

此表的关键作用是使用productId和validDate支持查询,并返回购买价格或未知

根据此设计,您可以设置访问视图(简单视图,物化视图或其他解决方案),提供订单的当前状态

 orderId, productId, orderDate, sellingPrice,
 DeliveryDate, -- NULL if not delivered
 purchasingDate,
 purchasingStaus -- 1 purchased, 0 - not yet purchased
 purchasingPrice

purchasingDate根据业务规则根据交付日期计算。 purchasingStatus是对报告日期和购买日期进行比较的结果。

purchasingPrice是估算产品的最后已知价格或正确的购买价格。

您可能还会问为什么数据仓库设计中的不变性很重要。 它类似于OLTP中的事务概念。在麻烦中,您可以使用审核维度 将数据回滚到某个点,然后重新加载。如果你更新,这要复杂得多。

小例子

在15.2。你在1月份获得了产品A的购买价格

采购价格表

 entryDate = 15.2.
 validFrom = 1.1.
 validTo = 31.1.
 purchacingPrice = 100

1.3上的产品订单A.在订单事件表

中创建记录
 orderDate = 1.3.
 sellingPrice = 200
 ...

您可以使用&#34;最后知道购买价格&#34;来报告此事件,目前为100。 (使用 orderDate 在采购价格表中查找没有给出有效结果,返回最后存储的值)

10.3交货。在投放活动表

中创建记录
 deliveryDate = 10.3.
 ....

确切的购买价格仍然未知(使用 deliveryDate 在采购价格表中查找没有给出有效结果,返回最后存储的值)

在15.4。新购买价格在3月的采购价格表中输入。 从这一点来看,真正的购买价格是已知的。