在MySQL中模拟滞后函数

| time | company | quote | +---------------------+---------+-------+ | 0000-00-00 00:00:00 | GOOGLE | 40 | | 2012-07-02 21:28:05 | GOOGLE | 60 | | 2012-07-02 21:28:51 | SAP | 60 | | 2012-07-02 21:29:05 | SAP | 20 | 

我如何在MySQL的这个表上做一个延迟来打印引号中的差异,例如:

 GOOGLE | 20 SAP | 40 

这是我最喜欢的MySQL黑客。

这就是你如何模仿滞后函数:

 SET @quot=-1; select time,company,@quot lag_quote, @quot:=quote curr_quote from stocks order by company,time; 
  • lag_quote拥有前一行报价的价值。 对于第一行@quot是-1。
  • curr_quote保存当前行的报价值。

笔记:

  1. order by子句在这里很重要,就像在一个常规的窗口函数中一样。
  2. 您可能还想使用company滞后,以确保您计算同一company报价差异。
  3. 你也可以用相同的方式实现行计数器@cnt:=@cnt+1

这种scheme的好处在于,与其他一些方法(如在应用程序服务器中使用聚合函数,存储过程或处理数据)相比,它在计算上非常精简。

编辑:

现在来谈谈以你提到的格式得到结果的问题:

 SET @quot=0,@latest=0,company=''; select B.* from ( select A.time,A.change,IF(@comp<>A.company,1,0) as LATEST,@comp:=A.company as company from ( select time,company,quote-@quot as change, @quot:=quote curr_quote from stocks order by company,time) A order by company,time desc) B where B.LATEST=1; 

嵌套是不相关的,所以不像看起来(语法上)那样不好(计算上):)

让我知道你是否需要任何帮助。

为了达到理想的结果,首先你需要find每个公司的最后和最后一个时间戳记。 以下查询非常简单:

 SELECT c.company, c.mts, max(l.ts) AS lts FROM (SELECT company, max(ts) AS mts FROM cq GROUP BY company) AS c LEFT JOIN cq l ON c.company = l.company AND c.mts > l.ts GROUP BY c.company, c.mts; 

现在,您必须将这个子查询与原始表连接起来才能获得所需的结果:

 SELECT c.company, l.quote, coalesce(l1.quote, 0), (l.quote - coalesce(l1.quote, 0)) AS result FROM (SELECT c.company, c.mts, max(l.ts) AS lts FROM (SELECT company, max(ts) AS mts FROM cq GROUP BY company) AS c LEFT JOIN cq l ON c.company = l.company AND c.mts > l.ts GROUP BY c.company, c.mts) AS c LEFT JOIN cq AS l ON l.company = c.company AND l.ts = c.mts LEFT JOIN cq AS l1 ON l1.company = c.company AND l1.ts = c.lts; 

您可以在SQL小提琴上观察结果。

此查询仅使用标准的SQLfunction,并且可以在任何RDBMS上工作。