0
id originator revenue date
-- ---------- ------- ----------
1  acme             1 2013-09-15
2  acme             0 2013-09-15
3  acme             4 2013-09-14
4  acme             6 2013-09-13
5  acme            -6 2013-09-13
6  hello            1 2013-09-15
7  hello            0 2013-09-14
8  hello            2 2013-09-13
9  hello            5 2013-09-14

我有上表。我想根据最近3天的收入根据发起人产生的收入添加排名列

要显示的字段如下:

originator revenue toprank
---------- ------- -------
hello            8       1
acme             5       2   

2)根据上述数据,我想根据以下标准计算产生的平均收入

如果同一日期的总收入总和为 0(零),则不应计入计算平均值。

a) 发起者 acme 的平均价值应该是收入/计数的总和(收入非零值的日期的数量),因此 (4+1)/2 即 2.5

b) 发起人 hello 的平均值应该是收入/计数的总和(收入非零值的日期的数量),因此 (5+2+1)/3 即 2.6666

originator revenue toprank avg(3 days)
---------- ------- ------- -----------
hello            8       1      2.6666
acme             5       2      2.5
4

2 回答 2

0

如果您想从今天的日期获取最近 3 天的值,请尝试以下操作:

SET @rank=0;

select originator, rev, @rank:=@rank+1 AS rank, avg 
FROM 
(select originator, sum(revenue) as rev, 
AVG(NULLIF(revenue, 0)) as avg
FROM t1
WHERE date >= DATE_ADD(CURDATE(), INTERVAL -3 DAY)
group by originator
order by 2 desc) as t2;

SQL小提琴..

编辑:

如果您想从最近的日期获取最近 3 天的值,请尝试以下操作:

SET @rank=0;

select originator, rev, @rank:=@rank+1 AS rank, avg 
from 
(select originator, sum(revenue) as rev, 
AVG(NULLIF(revenue, 0)) as avg
from t1
WHERE date >= DATE_ADD((select max(date) from t1), INTERVAL -3 DAY)
group by originator
order by 2 desc) as t2;

SQL小提琴..

于 2013-09-17T13:23:56.397 回答
0

要在平均时忽略一行,请给出AVG一个空值。该NULLIF功能对此很好。

MySQL 中的排名是有问题的。它不支持在 Oracle、MySQL、Teradata 等中更容易做到这一点的分析函数。最常见的解决方法是使用计数器变量,这需要一组有序的行,这意味着总收入必须在内部查询中计算。

SELECT originator, TotalRev, Avg3Days, @rnk := @rnk + 1 AS TopRank
FROM (
  SELECT
    originator,
    SUM(revenue) AS TotalRev,
    AVG(NULLIF(revenue, 0)) AS Avg3Days
  FROM myTable
  GROUP BY originator
  ORDER BY TotalRev DESC
) Tots, (SELECT @rnk := 0) Ranks
于 2013-09-17T13:17:30.563 回答