在纯SQL中使用加权

时间:2016-08-05 21:29:12

标签: mysql sql

我的前端(SourcePawn)目前执行以下操作:

float fPoints = 0.0;
float fWeight = 1.0;

while(results.FetchRow())
{
    fPoints += (results.FetchFloat(0) * fWeight);
    fWeight *= 0.95;
}

如果您不理解此代码,则会通过此查询的结果集:

SELECT points FROM table WHERE auth = 'authentication_id' AND points > 0.0 ORDER BY points DESC;

结果集是浮点数,按points从高到低排序。

我的前端占第一排的100%,然后是第二排的95%,每次下降5%。这一切都加起来fPoints,这是我的'sum'变量。

我正在寻找的是如何在纯SQL中复制此代码并在前端接收名为fPoints的总和的解决方案,因此我将能够运行它超过10,000行的表,在一个查询中而不是10,000个。

我很失落。我不知道从哪里开始,任何形式的指导都会非常好。

2 个答案:

答案 0 :(得分:3)

您可以使用变量执行此操作:

String entity = (String) outboundJaxrsResponse.getEntity();

关于计算的说明。 SELECT points, (points * (@f := 0.95 * @f) / 0.95) as fPoints FROM table t CROSS JOIN (SELECT @f := 1.0) params WHERE auth = 'authentication_id' AND points > 0.0 ORDER BY points DESC; 的值从1开始。因为我们正在处理变量,所以变量的赋值和使用需要在同一个表达式中--MySQL不保证表达式的求值顺序。

因此,@f将值减少了5%。但是,这适用于 next 迭代。 0.95 * @f撤消了迭代的正确值。

答案 1 :(得分:1)

虽然我很高兴回答Gordon Linoff为您提供了帮助,但您应该理解它非常具体。根据SQL标准,ORDER BY如何处理查询没有影响,并且SQL无法识别SELECT语句中的“迭代”。因此,“在每次迭代中减少变量”的想法,其中迭代顺序由ORDER BY控制,在标准SQL中没有基础。您可能想要检查它是否由MySQL保证,只是为了您自己的启发。

要以标准方式达到您想要的效果,请按以下步骤操作。

  1. 创建表格Percentiles( Percentile int not null, Factor float not null )
  2. 使用您的因子(20行)填充该表。
  3. 以降序编写ranks your points的视图或CTE。我们将等级列调用rank
  4. 然后加入你对Percentiles的看法:

    SELECT auth, sum(points * factor) as weight
    FROM "your view" as t join percentiles as p
    ON r.rank = percentile
    WHERE points > 0.0 
    GROUP BY auth
    

    该查询很简单,其意图很明显。 可能甚至更快。最重要的是,它肯定会起作用,并且不依赖于当前DBMS的任何特性。