组合不同频率的多个日期范围

时间:2017-07-10 22:22:02

标签: c# sql-server grouping intervals frequency

订单包含 startDate 跨度的开始日期, endDate 跨度的结束日期, unitAmount < / em>每次交付的单位数, frequencyAmount 每个频率交付单位的次数, frequencyId 交付的频率。例如:从2017-01-01到2017-04-01,每周有5个单位交付5次。它包括13个日历周,每周(6 * 5)个单元,整个订单总共390个单位。 可以在相同日期重叠创建多个订单。这是允许的,因为不可能每周3次写入2个单位的1个单位,每周1个单独的5个单位作为单个订单,也适用于不同的频率,例如每月1次10个单位。

问题:我无法找到验证这些订单是否超过某些设定限制的方法。例如,我想确保订单每月总计低于40个单位,我可能有4个订单相互重叠的不同日期跨度,单位和频率。 我想通过计算每个订单总共有多少单位以及订单的百分比与另一个订单重叠来组合所有订单。但是,当我验证更大的频率时,例如每年<1000个单位,而且我合并的订单量更小。我最终不得不推断并过高估计要求的单位数量。 (例如,订单比单个月合并为200个单位,这是好的,因为它只有一个月,但如果我计算每年的数量(200 * 12)它是1200和超过1000单位限制,但实际上总单位可能仍在。

Orders:
    |-----------------4 6x/week---------------|
                   |-------------8 1x/week-------------|
           |-------10 2x/month-------|

===========================================================
Combined Orders:
    |--a---|---b---|--------c--------|---d----|----e---|

我正在检查合并订单(a-e)的每个跨度是否超过任何每日,每周,每月或每年限制。不同的单位有不同的限制,我需要能够以这些不同的频率进行验证。

我觉得我这样做的方式不对,我一直在讨论这种方法的问题,例如在推断时我的高估。另一个问题,看看我的图表,每月2次10单位的第3个订单(假设订单是一个月),当合并时,分为2个跨度 b c < / strong>即可。 10个单位可以在 b 中交付两次, c 中没有,或者 b c b 中没有, c 中有两次。因此,如果我要转换为每周合并数量,我必须假设在最坏的情况下,总数单位在 b c 的范围内交付,这会导致高估。如果我弄清楚每个跨度的单位百分比,就会导致低估。

是否还有其他人遇到类似问题,或者是否有其他人认为他们有解决此问题的方法?

由于

编辑:另一种情况可能发生,想象每月限制30个单位:

Orders:
    |---10 units 2x/week---|       |---10 units 2x/week---|
2017-01-01                                           2017-01-31
===========================================================
Combined Orders:
    |--------20------------|       |----------20-----------|

在这种情况下,它超过了限制而不是由于重叠。这让我相信我还必须计算最早的startDate和最远的endDate之间每个月(或周,日,年)的单位数量。除非有更好的方法,但我觉得这是唯一的方法。

1 个答案:

答案 0 :(得分:0)

除了@Furmek在他的第3条评论中提出的建议,我没有看到任何其他方式。 该解决方案的原型如下。

-- Here we calculate daily unit amount for all orders that overlap a validation period.
-- [frequency] is in days
;WITH ValidationPeriodOrders AS(
SELECT ( unitAmount * frequencyAmount ) / [frequency] AS AvgDailyAmount
    -- Adjust order dates to be within Validation period
    CASE WHEN startDate < ValidationPeriodStart THEN ValidationPeriodStart ELSE startDate END AS OrderStart,
    CASE WHEN endDate > ValidationPeriodEnd THEN ValidationPeriodEnd ELSE endDate END AS OrderEnd
FROM Order
-- Look for orders that fall inside a validation period
WHERE endDate BETWEEN ValidationPeriodStart AND ValidationPeriodEnd
    OR startDate BETWEEN ValidationPeriodStart AND ValidationPeriodEnd
)
-- Get total units per validation period
SELECT SUM( AvgDailyAmount * DATEDIFF( dd, OrderStart, OrderEnd ))
FROM ValidationPeriodOrders

由于没有(可靠的)方法来判断订单何时交付,我建议将数字四舍五入(而不是数学四舍五入)。