MySQL计算列滞后返回

时间:2013-05-11 13:58:59

标签: php mysql lag calculated-columns

我有一个带有计算列的MySQL查询。

出于某种原因,在第一次运行时,查询在计算列中返回NULL。 在刷新(即第二次运行)时,它正确地返回计算值。 我该如何摆脱这种滞后?

请参阅以下查询:

SELECT @P0:=MAX(CASE WHEN t2.date IS NULL THEN t1.price ELSE NULL END),

@P1:=MAX(CASE WHEN t3.date IS NULL THEN t1.price ELSE NULL END),

ROUND(100*(@P1-@P0)/@P0,1) AS 'r1y'
/* The r1y above is the calculated column that is returned with lag*/

FROM (SELECT date, price FROM mytable
WHERE ticker='XYZ'
AND date>=@t1:=(SELECT DATE_SUB((SELECT MAX(date) FROM mytable), 
INTERVAL 1 YEAR))) AS t1

LEFT OUTER JOIN (SELECT date FROM mytable
where ticker='XYZ'
AND date>=@t1) AS t2 
ON (t1.date>t2.date)

LEFT OUTER JOIN (SELECT date FROM mytable
WHERE ticker='XYZ'
AND date>=@t1) AS t3 
ON (t1.date<t3.date)

当我将'r1y'的计算移出MySQL并进入代码的PHP部分时,当然没有滞后。尽管如此,在MySQL中进行所有计算仍然是件好事。

更新

这是更容易的查询,返回相同的结果,没有滞后(执行时间大致相同):

SELECT 
@d1:=(SELECT MAX(date) FROM mytable WHERE ticker='XYZ' AND current=1),
@d2:=(SELECT MIN(date) FROM mytable WHERE ticker='XYZ' 
AND date>=DATE_SUB(@d1, INTERVAL 1 YEAR)),
@m1:=(SELECT price FROM mytable WHERE ticker='XYZ' AND date=@d1),
@m2:=(SELECT price FROM mytable WHERE ticker='XYZ' AND date=@d3),
ROUND(100*(@m1-@m2)/@m2, 1) as r1y

了解上述延迟的性质仍然很好,但这个建议的解决方案对我来说很好。

1 个答案:

答案 0 :(得分:1)

您在此处设置@ t1的值:

FROM (SELECT date, price
      FROM mytable
      WHERE ticker='XYZ' AND
            date>=@t1:=(SELECT DATE_SUB((SELECT MAX(date) FROM mytable
                                        ), INTERVAL 1 YEAR
                                       )
                       )
    ) AS t1

然后,您将在后续子查询中使用它。

SQL 保证加入处理顺序。 MySQL也没有。您的查询第一次不起作用的原因是因为第一个子查询没有首先执行。

可能最简单的解决方法是在原始查询的每个部分重复子查询 - 但要确保date上有一个索引,以便快速评估。