mysql根据条件限制比较中的行数

to94eoyn  于 2021-06-20  发布在  Mysql
关注(0)|答案(2)|浏览(464)

我有一个表“我的表”有两列

1. Timestamp (ts)
 2. Value (val)

我需要为每个时间戳返回在时间戳上或之前出现的10个最新值的平均值。
我可以通过以下查询执行类似操作:

SELECT t2.ts as time, 
       AVG(t1.val) as avg_val 
FROM table_name as t1, table_name as t2 
WHERE t1.ts <= t2.ts

它返回一个时间戳和在该时间戳上或之前出现的所有值的平均值。我需要修改此查询以返回10个最新值的平均值,而不是所有值。
附言:抱歉问得不好。我不知道怎么装帧。

bnlyeluc

bnlyeluc1#

在8版之前的mysql中,没有一种简单的方法来表达这个查询——甚至使用变量。我不会为你的表现担保,但这应该是你想要的:

SELECT t1.ts, t1.val, AVG(t2.val)
FROM t t1 LEFT JOIN
     t t2
     ON t2.ts <= t.ts AND
        t2.ts >= (SELECT t3.ts
                  FROM t t3
                  WHERE t3.ts <= t1.ts
                  ORDER BY t3.ts DESC
                  LIMIT 9, 1
                 )
GROUP BY t1.ts, t1.val;

当然,在8+中,这只是:

select t.*,
       avg(t.val) over (order by ts rows between 9 preceding and current row) as avg_10
from t;
edqdpe6u

edqdpe6u2#

忽略前面的答案。您可以使用“穷人的排名”对按时间戳排序的行进行排名。对于“查找每个列组的前9行”,您可以单独联接结果:

SELECT a.ts, AVG(c.val)
FROM (
    SELECT t1.ts, COUNT(t2.ts) AS rank
    FROM t AS t1
    INNER JOIN t AS t2 ON t2.ts <= t1.ts
    GROUP BY t1.ts
) AS a
INNER JOIN (
    SELECT t1.ts, COUNT(t2.ts) AS rank
    FROM t AS t1
    INNER JOIN t AS t2 ON t2.ts <= t1.ts
    GROUP BY t1.ts
) AS b ON b.rank BETWEEN a.rank - 9 AND a.rank
INNER JOIN t AS c ON b.ts = c.ts
GROUP BY a.ts

我知道它有点笨拙,但在某些条件下,它可能比相关子查询更好。

相关问题