sur*_*190 9 mysql sql database
美好的一天,
我使用以下代码计算9天移动平均值.
SELECT SUM(close)
FROM tbl
WHERE date <= '2002-07-05'
AND name_id = 2
ORDER BY date DESC
LIMIT 9
Run Code Online (Sandbox Code Playgroud)
但它不起作用,因为它在调用限制之前首先计算所有返回的字段.换句话说,它将计算在该日期之前或之前的所有关闭,而不仅仅是最后的9.
所以我需要从返回的select中计算SUM,而不是直接计算它.
IE浏览器.从SELECT中选择SUM ...
现在我将如何做到这一点,它是否非常昂贵,还是有更好的方法?
Gor*_*off 12
如果你想要每个日期的移动平均线,那么试试这个:
SELECT date, SUM(close),
(select avg(close) from tbl t2 where t2.name_id = t.name_id and datediff(t2.date, t.date) <= 9
) as mvgAvg
FROM tbl t
WHERE date <= '2002-07-05' and
name_id = 2
GROUP BY date
ORDER BY date DESC
Run Code Online (Sandbox Code Playgroud)
它使用相关子查询来计算9个值的平均值.
从 MySQL 8 开始,您应该为此使用窗口函数。使用windowRANGE子句,你可以在一个区间上创建一个逻辑窗口,这个功能非常强大。像这样的东西:
SELECT
date,
close,
AVG (close) OVER (ORDER BY date DESC RANGE INTERVAL 9 DAY PRECEDING)
FROM tbl
WHERE date <= DATE '2002-07-05'
AND name_id = 2
ORDER BY date DESC
Run Code Online (Sandbox Code Playgroud)
例如:
WITH t (date, `close`) AS (
SELECT DATE '2020-01-01', 50 UNION ALL
SELECT DATE '2020-01-03', 54 UNION ALL
SELECT DATE '2020-01-05', 51 UNION ALL
SELECT DATE '2020-01-12', 49 UNION ALL
SELECT DATE '2020-01-13', 59 UNION ALL
SELECT DATE '2020-01-15', 30 UNION ALL
SELECT DATE '2020-01-17', 35 UNION ALL
SELECT DATE '2020-01-18', 39 UNION ALL
SELECT DATE '2020-01-19', 47 UNION ALL
SELECT DATE '2020-01-26', 50
)
SELECT
date,
`close`,
COUNT(*) OVER w AS c,
SUM(`close`) OVER w AS s,
AVG(`close`) OVER w AS a
FROM t
WINDOW w AS (ORDER BY date DESC RANGE INTERVAL 9 DAY PRECEDING)
ORDER BY date DESC
Run Code Online (Sandbox Code Playgroud)
导致:
date |close|c|s |a |
----------|-----|-|---|-------|
2020-01-26| 50|1| 50|50.0000|
2020-01-19| 47|2| 97|48.5000|
2020-01-18| 39|3|136|45.3333|
2020-01-17| 35|4|171|42.7500|
2020-01-15| 30|4|151|37.7500|
2020-01-13| 59|5|210|42.0000|
2020-01-12| 49|6|259|43.1667|
2020-01-05| 51|3|159|53.0000|
2020-01-03| 54|3|154|51.3333|
2020-01-01| 50|3|155|51.6667|
Run Code Online (Sandbox Code Playgroud)
使用类似的东西
SELECT
sum(close) as sum,
avg(close) as average
FROM (
SELECT
(close)
FROM
tbl
WHERE
date <= '2002-07-05'
AND name_id = 2
ORDER BY
date DESC
LIMIT 9 ) temp
Run Code Online (Sandbox Code Playgroud)
内查询返回所有在过滤的行desc顺序,然后avg,sum向上的行返回.
query您给出的不起作用的原因是由于sum首先计算并且在已经计算LIMIT之后应用该子句sum,因此给出了sum所有存在的行