帐单日期的平均月份范围

时间:2018-08-02 14:25:53

标签: tsql

我们的计费系统有一张位置表。这些地点每个月都会产生一张帐单。这些帐单每月可能有几天的差异(例如,一个月6日结算,然后下一个月8日结算)。不过,它们总是在一个月的同一时间停留。我需要提出一个“停电”范围,该范围实际上是过去X个月中对该位置开帐单的月份的任何一天。它需要适当地计算可能在月底/月初之间反弹的位置。

为此,唯一相关的表是位置表和账单表。 Loc Table包含位置列表,其中LocationID为PK。我相信其他领域与此无关。有一个票据表,其文档编号为PK,位置ID为FK。此外,还有许多其他字段,例如文档金额,到期日等。它还具有“开票日期”,这是我要从中计算“停电”日期的日期。

基本上,我们将更改每米的价格,并且不想在可能要收费的日子进行更改。

示例数据:

位置:

111111,Field1,Field2等

222222,Field1,Field2等

帐单(DocNum,LocationID,BillingDate):

BILL0001,111111,1/6/2018

BILL0002、111111、2018年2月8日

BILL0003、111111、3 / 5/2018

BILL0004,111111,4/6/2018

BILL0005,111111,2018/5/11

BILL0006,111111,6/10/2018

BILL0007、111111、7 / 9/2018

BILL0008,222222,1/30/2018

BILL0009,222222,3/1/2018

BILL0010,222222,2018/4/2

BILL0011,222222,5/3/2018

BILL0012,222222,6/1/2018

BILL0013,222222,2018年7月1日

BILL0014,222222,2018年7月28日

示例输出:

位置:111111停电时间:6日-11日

位置:222222停电时间:28日-3日

我该怎么做?

1 个答案:

答案 0 :(得分:0)

据我了解,您想算出帐单发生的“平均”天,然后据此构建日期范围?

我能想到的最准确的方法是计算距离函数,然后尝试找出使该距离函数最小化的月份中的某天。 一个示例函数为:

  

distance()= Min((Day(BillingDate)-TrialDayNumber)%30,(TrialDayNumber-Day(BillingDate))%30)

这将产生一个0到15之间的数字,告诉您帐单日期与每月TrialDayNumber的任意一天相距多远。

您希望尝试选择平均距离值最低的一天,因为这将是最接近您的结算日的月份。如果您可以在SQL之外执行计算(例如,如果将数据导出到Excel或SSRS),则这种优化功能的计算将更加容易。

我相信您可以完全使用SQL来计算它,但这非常棘手。我可以为每个DayOfTheMonth /位置ID组合生成一个具有距离结果的表,但是当我尝试将其缩小到每个位置的最佳距离时,卡住了。

WITH DaysOfTheMonth as(
SELECT 1 as DayNumber
UNION ALL
SELECT DayNumber + 1 as DayNumber
FROM DaysOfTheMonth
WHERE AutoNumber < 31
)
SELECT Bills.LocationID, DaysOfTheMonth.DayNumber,
Avg((Day(Bills.BillingDate)-DaysOfTheMonth.DayNumber)%30) as Distance
FROM Bills, DaysOfTheMonth
GROUP BY Bills.LocationID, DaysOfTheMonth.DayNumber

这种方法的一大缺点是计算量大。