社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

如何在mysql 5.7中使用lag()函数[duplicate]

devRena • 4 年前 • 1048 次点击  
| 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  
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/41251
 
1048 次点击  
文章 [ 3 ]  |  最新文章 4 年前
vyegorov
Reply   •   1 楼
vyegorov    11 年前

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

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 Fiddle .

这个查询只使用标准的sql功能,应该可以在任何rdbms上运行。

Lukasz Szozda
Reply   •   2 楼
Lukasz Szozda    6 年前

在mysql 8.0及以上版本中,不需要模拟 LAG . 它是本机支持的,

Window Function :

从当前行在其分区内滞后(先于)n行的行中返回expr的值。如果没有这样的行,则返回默认值。例如,如果n为3,则前两行的返回值为默认值。如果缺少n或default,则默认值分别为1和null。

SELECT
     company,
     quote,
     LAG(quote) OVER(PARTITION BY company ORDER BY time) AS prev_quote
FROM tab;

DBFiddle Demo

Dojo
Reply   •   3 楼
Dojo    11 年前

这是我最喜欢的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. 您可能还想使用lag company 只是为了确定你在计算同一个报价的差异 公司 .
  3. 也可以用同样的方法实现行计数器 @cnt:=@cnt+1

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

编辑:

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

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;

嵌套不是相互关联的,所以没有看上去那么糟糕(从计算上讲):)

如果你需要帮助,请告诉我。