查询结果的偏移量
Offset on query results
我正在尝试比较每周结果。更具体地说,我想一周又一周地得到差异。
首先我想展示一下结果应该是怎样的:
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
我的问题是,运行 子查询需要花费大量时间(我为这个展示做了简化)。 SELECT
和 COUNT()
运行 45 秒。每个 = 1.5 分钟。我认为应该有一个更合适的解决方案。我只需要 prev_value 移动 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
中表达式的执行顺序).几乎所有其他数据库都支持lag()
用于此目的,这使得查询更快,逻辑更简单。
我正在尝试比较每周结果。更具体地说,我想一周又一周地得到差异。
首先我想展示一下结果应该是怎样的:
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
我的问题是,运行 子查询需要花费大量时间(我为这个展示做了简化)。 SELECT
和 COUNT()
运行 45 秒。每个 = 1.5 分钟。我认为应该有一个更合适的解决方案。我只需要 prev_value 移动 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
中表达式的执行顺序).几乎所有其他数据库都支持lag()
用于此目的,这使得查询更快,逻辑更简单。