在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
保存当前行的报价值。
笔记:
-
order by
子句在这里很重要,就像在一个常规的窗口函数中一样。 - 您可能还想使用
company
滞后,以确保您计算同一company
报价差异。 - 你也可以用相同的方式实现行计数器
@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上工作。