Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL中的lag函数模拟_Mysql_Sql_Sliding Window - Fatal编程技术网

MySQL中的lag函数模拟

MySQL中的lag函数模拟,mysql,sql,sliding-window,Mysql,Sql,Sliding Window,如何在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-

如何在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  
lag_quote保存前一行的quote值。对于第一行,@quot是-1。 curr_quote保存当前行的quote值。 注:

ORDERBY子句在这里很重要,就像在正则表达式中一样 窗口功能。 您可能还希望为公司使用lag,以确保计算的是同一公司报价中的差异。 您还可以使用@cnt:=@cnt+1的相同方式实现行计数器 该方案的优点在于,与其他一些方法(如在ApplicationServer中使用聚合函数、存储过程或处理数据)相比,它在计算上非常精简

编辑:

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

SET @quot=-1;
select time,company,@quot lag_quote, @quot:=quote curr_quote
  from stocks order by company,time;
嵌套不是相互关联的,因此在计算上没有语法上看起来那么糟糕:


如果您需要任何帮助,请告诉我。

要获得所需的结果,首先您需要找到每个公司的最后和下一个时间戳。以下查询非常简单:

选择c.company、c.mts、maxl.ts作为lts 从选择的公司,按公司c从cq GROUP中选择maxts作为mts 左连接cq l 在c.company=l.company和c.mts>l.ts上 c.company集团,c.mts; 现在,您必须将此子查询与原始表联接以获得所需的结果:

选择c.company、l.quote、coalescle1.quote、0、, l、 quote-合并1.quote,结果为0 从中选择c.company、c.mts、maxl.ts作为lts 从选择的公司,按公司c从cq GROUP中选择maxts作为mts 左连接cq l 在c.company=l.company和c.mts>l.ts上 集团由c.company,c.mts作为c 左键作为l.company=c.company和l.ts=c.mts上的l加入cq 在l1.company=c.company和l1.ts=c.lts上作为l1左键加入cq; 您可以在上观察结果


此查询仅使用标准SQL功能,应可用于任何RDBMS。

从MySQL 8.0及更高版本开始,无需模拟延迟。它是本地支持的

:

从位于当前行之前的行中返回expr的值,该行在其分区内落后于N行。如果没有此类行,则返回值为默认值。例如,如果N为3,则返回值为前两行的默认值。如果缺少N或default,则默认值分别为1和NULL


每个公司只有两个吗?或者它是可变的?我看到这里有两个公司,但每个公司只有两行吗?如果是这样的话,您可以简单地使用MAX-MIN聚合。如果每个公司有2行以上,就更复杂了。我只需要最新的两个时间戳。。同一家公司可能有很多条目,但我只需要取最新的两个时间戳并打印报价差异。如果一家公司仅由一行表示,您想在结果中返回该公司吗?如果是这样的话,应该为其返回什么差异?在您的示例中,为什么其中一家公司的结果不是负值?谷歌从40岁上升到60岁,而SAP则从60岁下降到20岁。或者你只想要绝对运动,而不考虑方向,在这种情况下,我得到了错误。MySQL的查询面板中不允许使用DDL和DML语句;只允许SELECT语句。将DDL和DML放在架构面板中。尽管错误没有表明这一点,但请尝试启用allowMultiQueries。这是一个连接器参数。有关JDBC连接器,请参阅:。您能从MySQL客户端成功运行它吗?您也可以尝试在同一会话中单独执行这两条语句。@javanx您好,我是SQL FIDLE的作者。您提到的错误消息实际上是我在处理某些类型的MySQL查询时遇到的一个bug。感谢您在这里的留言,我认识到了这一点,并制定了一个解决方案来修复它。请参见此处,例如:。谢谢注意:必须使变量的数据类型与试图滞后的数据类型保持一致。例如,如果要累加浮点字段,必须将变量初始化为@quot=0.0,否则它将无法工作。我花了一分钟才弄明白!很好的回答,尤其是对于准备技术面试的人,因为他们通常不鼓励使用窗口功能。
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;
SELECT
     company,
     quote,
     LAG(quote) OVER(PARTITION BY company ORDER BY time) AS prev_quote
FROM tab;