Mysql 查询结果的偏移量

Mysql 查询结果的偏移量,mysql,sql,join,subquery,offset,Mysql,Sql,Join,Subquery,Offset,我试着比较每周的结果。更具体地说,我想一周接一周地得到差异 首先,我想展示一下结果应该是什么样子: CalendarWeek currently previous_week delta 2016-01 200 2016-02 210 200 10 2016-03 205 210 -5

我试着比较每周的结果。更具体地说,我想一周接一周地得到差异

首先,我想展示一下结果应该是什么样子:

CalendarWeek     currently      previous_week      delta
2016-01          200            
2016-02          210            200                 10
2016-03          205            210                 -5
2016-04          230            205                 25
...      
我找到了一个解决方案,但速度很慢

目前我是这样做的:

SELECT CalendarWeek, cur_value - prev_value AS delta
FROM  
    (SELECT CalendarWeek, COUNT(Change_ID) AS cur_value
     FROM Changes
     WHERE ...
     GROUP BY CalendarWeek) AS cur_week
LEFT JOIN
    (SELECT CalendarWeek, COUNT(Change_ID) AS prev_value
     FROM Changes
     WHERE ...
     GROUP BY CalendarWeek) AS prev_week
ON cur_week.CalendarWeek = prev_week.CalendarWeek + 1
我的问题是,运行子查询需要很多时间(我在这个展示中简化了它们)。使用
COUNT()
运行45秒的
选择
。每个=1,5分钟。我认为应该有一个更合适的解决方案。我只需要将prev_值移动1行或偏移1行。

使用变量:

SELECT w.*,
       (CASE WHEN (@pcv := @prev_value) = NULL THEN NULL       -- never happens
             WHEN (@prev_value := cur_value) = NULL THEN NULL  -- never happens
             ELSE @pcv
        END) as prev_value
FROM (SELECT CalendarWeek, COUNT(Change_ID) AS cur_value
      FROM Changes
      WHERE ...
      GROUP BY CalendarWeek AS cur_week
     ) w CROSS JOIN
     (SELECT @prev_value := -1) params
ORDER BY CalendarWeek;
然后可以使用附加的子查询来计算比率和差异

注:分配上一个值的逻辑是一个三步过程:(1)在变量中缓存上一个值,(2)重新分配上一个值,以及(3)然后使用缓存的值


MySQL不保证
SELECT
中表达式的执行顺序,因此这一切都必须发生在单个表达式中(因此
=NULL
,这永远不会是真的)。几乎所有其他数据库都支持用于此目的的
lag()
,这使得查询速度更快,逻辑更简单。

谢谢。它工作正常。缓存这些值真是个好主意。这正是我要找的!交叉联接前面只有一个括号太多。:)