在SQL中将一个运算的结果乘以运算n次?
Multiply the result of an operation by the operation n times in SQL?
我正在尝试在 SQL 中实现一种基于流逝时间的衰减机制。因此,随着时间的推移,该项目 "decays" 会更快(基于之前的产品)。
这是通过具有 "Decay" 值、生成日期和周期性(即衰减值应用之间的时间量)来实现的。
所以如果一个项目有 25% 的衰减,从 1 开始,生成日期是今天和 3.5 分钟前,它已经衰减了 3 倍,导致 'weighted value':
1m - 1.25
2m - 1.5625
3m - 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 语句中确定一些内容,以阻止我按太旧且会导致溢出的项目进行排序,或者至少将其最大化到最大值小数点。
试试这个
SET ARITHABORT OFF;
SET ARITHIGNORE ON;
SET ANSI_WARNINGS OFF;
这不会挂起溢出错误,而是 return null
最后编辑 Null
select MyDate
from MyTable
order by case when MyDate is null then 1 else 0 end, MyDate
假设 s > 0
和 d > 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])
请注意,您将忽略在此 table 上定义的 任何 索引,因为您是通过计算操作进行排序的。如果这是您希望经常执行的操作,请考虑添加一个带有上述表达式索引的计算列或您执行(例如)每小时更新的静态列。
我正在尝试在 SQL 中实现一种基于流逝时间的衰减机制。因此,随着时间的推移,该项目 "decays" 会更快(基于之前的产品)。
这是通过具有 "Decay" 值、生成日期和周期性(即衰减值应用之间的时间量)来实现的。
所以如果一个项目有 25% 的衰减,从 1 开始,生成日期是今天和 3.5 分钟前,它已经衰减了 3 倍,导致 'weighted value':
1m - 1.25
2m - 1.5625
3m - 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 语句中确定一些内容,以阻止我按太旧且会导致溢出的项目进行排序,或者至少将其最大化到最大值小数点。
试试这个
SET ARITHABORT OFF;
SET ARITHIGNORE ON;
SET ANSI_WARNINGS OFF;
这不会挂起溢出错误,而是 return null
最后编辑 Null
select MyDate
from MyTable
order by case when MyDate is null then 1 else 0 end, MyDate
假设 s > 0
和 d > 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])
请注意,您将忽略在此 table 上定义的 任何 索引,因为您是通过计算操作进行排序的。如果这是您希望经常执行的操作,请考虑添加一个带有上述表达式索引的计算列或您执行(例如)每小时更新的静态列。