1

我一直在为一个具有以下表格结构的项目工作

开始 | 结束 | 速度
------------------
   1 | 50 | 10
  51 | 100 | 20
 101 | 150 | 40
 151 | 200 | 80
 201 | 0 |100

这里最后一条记录意味着 200 到无限值的比率为 100

在这里,我必须根据用户给出的开始和结束值来计算总费率

我在 mysql 中尝试了以下查询,输入 start - 30, end - 170

SELECT SUM((end+1 - start) * amount) 
FROM table 
WHERE start > 30
AND end < 170

它只给出第二条和第三条记录值的总和,然后我必须分别查询第一条和最后一条记录。

我怎样才能在单个查询中实现这一点?

4

3 回答 3

1

基于 lc. 的算法,你可以在 MySQL 中运行它:

SET @start = 30, @end = 170;

SELECT
  sum(rate * (least(`end`, @end) - greatest(start, @start) + 1)) TotalRate
FROM Table1
WHERE @end >= start OR @start <= `end`
于 2013-10-07T06:04:30.480 回答
1

假设我们声明了以下两个参数:

set @start = 30, @end = 170;

首先要获得属于您范围内的行(重叠),我们会这样做(SQL Fiddle):

select start, end
from Table1
where start <= @end OR end >= @start

然后我们按摩第一行和最后一行的范围的开始和结束。基本上,我们将范围的第一部分和范围@start的第二部分限制在@endSQL Fiddle):

select CASE WHEN @start > start THEN @start ELSE start END AS start, 
    CASE WHEN @end < end THEN @end ELSE end END AS end
from Table1
where start <= @end OR end >= @start

然后我们可以将这两个case表达式相减得到距离。如果您想要包含距离(SQL Fiddle),请不要忘记添加 1:

select CASE WHEN @end < end THEN @end ELSE end END - CASE WHEN @start > start THEN @start ELSE start END + 1 AS dist
from Table1
where start <= @end OR end >= @start

乘以比率。这次不要忘记括号,因为乘法优先(SQL Fiddle):

select rate * (CASE WHEN @end < end THEN @end ELSE end END - CASE WHEN @start > start THEN @start ELSE start END + 1)
from Table1
where start <= @end OR end >= @start

最后,SUM在整个表达式周围加上 a 以将其全部加起来(SQL Fiddle):

select SUM(rate * (CASE WHEN @end < end THEN @end ELSE end END - CASE WHEN @start > start THEN @start ELSE start END))
from Table1
where start <= @end OR end >= @start
于 2013-10-07T05:39:10.890 回答
0

基于@lc Suggestion,以下查询适合我的期望

    SET @start=30, @end=170;
    SELECT SUM(rat*(CASE WHEN @end < end or end=0 THEN @end ELSE end END - CASE WHEN @start > start THEN @start ELSE start-1 END)) as price
    FROM rate
    WHERE start <= @end and (end >= @start or end=0)

并且此查询满足以下所有条件

当 start-60, end-140 那么数学将是(40*20)+(40*40)=2400

当 start-230,end 270 那么数学将是(40*100)=400

于 2013-10-07T07:30:28.810 回答