2016-03-14 85 views
1

我試圖在SQL中實現衰減機制,是基於已過去了的時間量。所以隨着時間的推移,項目會「衰減」(基於以前的產品)。在SQL中將操作的結果乘以n次操作?

這是通過具有「衰減」值,生成的日期和AKA的時間的衰減值的應用之間的量的週期性來完成。

所以如果一個項目有25%的衰減,從1開始,隨着新一代今天和一個日起3分鐘前,將已經腐爛導致「權重值3倍:

1米 - 1.25

2米 - 1.5625

3米 - 1.953125

s * ((1+d)^n) 
where 
s = starting value 
d = decay % as decimal 
n = number of elapsed periods 

對於相關的SQL之中:

ORDER BY 

    1.00 * POWER((1.00+[Decay]),CONVERT(float, DATEDIFF(minute,[GenerationDate],GETUTCDATE()))) 

然而這會導致溢出,所以我現在決定在WHERE語句東西會阻止我由是太舊,導致溢出的物品訂購,或者至少使其達到小數的最大值。

回答

2

假設s > 0d > 0,那麼你可以利用事實,即有序的實物集X它的訂單在轉換Y = Log(X)下保存。把你的函數的Log,你會得到一個適合緊湊的IEEE浮點的實數:

X = s * ((1+d)^n) 
Log(X) = Log(s * ((1 + d)^n))) 
Log(X) = Log(s) + Log((1 + d)^n) 
Log(X) = Log(s) + n * Log(1 + d) 

則走的事實,Log(s)是常數項您簡化到以下ORDER BY優勢:

ORDER BY 
    CONVERT(float, DATEDIFF(minute, [GenerationDate], GETUTCDATE())) * Log(1.00+[Decay]) 

要知道,你會忽略你已經在這個表上,因爲你由計算機操作訂購定義的任何指數。如果這是您期望經常執行的操作,請考慮添加一個帶有上述表達式的索引的計算列或您在其上執行(例如)每小時更新的靜態列。

+1

參見維基百科的文章[對數恆等式(https://en.wikipedia.org/wiki/Logarithm#Logarithmic_identities) –

+0

我喜歡這個。雖然我記得有關從學校登錄的東西,但我從未想過我會看到真實的生活示例:) – kurin123

1

試試這個

SET ARITHABORT OFF; 
SET ARITHIGNORE ON; 
SET ANSI_WARNINGS OFF; 

這不會掛在溢出錯誤,但將返回null,而不是

編輯Null作爲最後

select MyDate 
from MyTable 
order by case when MyDate is null then 1 else 0 end, MyDate 
+0

這個我已經找到了,但我遇到麻煩零點到正確排序。真的,我知道不是空值意味着它們比空值小,所以我需要數字,然後是空值。對此有何想法? –

+0

試試這個[null作爲最後](http://stackoverflow.com/questions/1498648/sql-how-to-make-null-values-come-last-when-sorting-ascending) – kurin123